aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-07-13 17:21:42 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-07-13 17:21:42 +0000
commit4ba675006b5a8edfc48b6a9bd3dcf54a70cc08f2 (patch)
tree48b44512b5db8ced345df4a1a56b5065cf2a14d9 /include/clang
parentd7279c4c177bca357ef96ff1379fd9bc420bfe83 (diff)
downloadsrc-4ba675006b5a8edfc48b6a9bd3dcf54a70cc08f2.tar.gz
src-4ba675006b5a8edfc48b6a9bd3dcf54a70cc08f2.zip
Update clang to r108243.vendor/clang/clang-r108243
Notes
Notes: svn path=/vendor/clang/dist/; revision=210008 svn path=/vendor/clang/clang-r108243/; revision=210076; tag=vendor/clang/clang-r108243
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h121
-rw-r--r--include/clang/AST/Attr.h229
-rw-r--r--include/clang/AST/CMakeLists.txt15
-rw-r--r--include/clang/AST/CanonicalType.h3
-rw-r--r--include/clang/AST/Decl.h243
-rw-r--r--include/clang/AST/DeclBase.h50
-rw-r--r--include/clang/AST/DeclCXX.h206
-rw-r--r--include/clang/AST/DeclFriend.h7
-rw-r--r--include/clang/AST/DeclObjC.h42
-rw-r--r--include/clang/AST/DeclTemplate.h310
-rw-r--r--include/clang/AST/DeclVisitor.h17
-rw-r--r--include/clang/AST/Expr.h143
-rw-r--r--include/clang/AST/ExprCXX.h220
-rw-r--r--include/clang/AST/ExternalASTSource.h103
-rw-r--r--include/clang/AST/Makefile20
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h1913
-rw-r--r--include/clang/AST/Redeclarable.h5
-rw-r--r--include/clang/AST/Stmt.h75
-rw-r--r--include/clang/AST/StmtIterator.h1
-rw-r--r--include/clang/AST/TemplateBase.h26
-rw-r--r--include/clang/AST/TemplateName.h11
-rw-r--r--include/clang/AST/Type.h212
-rw-r--r--include/clang/AST/TypeLoc.h126
-rw-r--r--include/clang/AST/TypeLocBuilder.h9
-rw-r--r--include/clang/AST/TypeNodes.def1
-rw-r--r--include/clang/AST/UsuallyTinyPtrVector.h11
-rw-r--r--include/clang/Analysis/Analyses/PrintfFormatString.h214
-rw-r--r--include/clang/Analysis/Support/BumpVector.h1
-rw-r--r--include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h62
-rw-r--r--include/clang/Basic/Attr.td382
-rw-r--r--include/clang/Basic/AttrKinds.h31
-rw-r--r--include/clang/Basic/Builtins.def1
-rw-r--r--include/clang/Basic/BuiltinsARM.def8
-rw-r--r--include/clang/Basic/BuiltinsPPC.def111
-rw-r--r--include/clang/Basic/CMakeLists.txt12
-rw-r--r--include/clang/Basic/DeclNodes.td70
-rw-r--r--include/clang/Basic/Diagnostic.h56
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td1
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td8
-rw-r--r--include/clang/Basic/DiagnosticGroups.td13
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td5
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td19
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td183
-rw-r--r--include/clang/Basic/IdentifierTable.h6
-rw-r--r--include/clang/Basic/LangOptions.h47
-rw-r--r--include/clang/Basic/Makefile41
-rw-r--r--include/clang/Basic/PartialDiagnostic.h12
-rw-r--r--include/clang/Basic/SourceLocation.h50
-rw-r--r--include/clang/Basic/StmtNodes.td (renamed from include/clang/AST/StmtNodes.td)11
-rw-r--r--include/clang/Basic/TargetInfo.h29
-rw-r--r--include/clang/Basic/TargetOptions.h8
-rw-r--r--include/clang/Basic/Version.h10
-rw-r--r--include/clang/Basic/Version.inc.in6
-rw-r--r--include/clang/Basic/arm_neon.td341
-rw-r--r--include/clang/Checker/AnalysisConsumer.h35
-rw-r--r--include/clang/Checker/BugReporter/BugReporter.h1
-rw-r--r--include/clang/Checker/FrontendActions.h29
-rw-r--r--include/clang/Checker/PathDiagnosticClients.h (renamed from include/clang/Frontend/PathDiagnosticClients.h)4
-rw-r--r--include/clang/Checker/PathSensitive/Checker.h30
-rw-r--r--include/clang/Checker/PathSensitive/CheckerVisitor.h9
-rw-r--r--include/clang/Checker/PathSensitive/Environment.h2
-rw-r--r--include/clang/Checker/PathSensitive/ExplodedGraph.h10
-rw-r--r--include/clang/Checker/PathSensitive/GRCoreEngine.h18
-rw-r--r--include/clang/Checker/PathSensitive/GRExprEngine.h31
-rw-r--r--include/clang/Checker/PathSensitive/GRState.h27
-rw-r--r--include/clang/Checker/PathSensitive/GRSubEngine.h28
-rw-r--r--include/clang/Checker/PathSensitive/GRTransferFuncs.h2
-rw-r--r--include/clang/Checker/PathSensitive/MemRegion.h77
-rw-r--r--include/clang/Checker/PathSensitive/SVals.h4
-rw-r--r--include/clang/Checker/PathSensitive/SValuator.h8
-rw-r--r--include/clang/Checker/PathSensitive/Store.h31
-rw-r--r--include/clang/Checker/PathSensitive/SymbolManager.h43
-rw-r--r--include/clang/CodeGen/BackendUtil.h37
-rw-r--r--include/clang/CodeGen/CodeGenAction.h (renamed from include/clang/Frontend/CodeGenAction.h)9
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h3
-rw-r--r--include/clang/Driver/Action.h13
-rw-r--r--include/clang/Driver/Arg.h181
-rw-r--r--include/clang/Driver/ArgList.h97
-rw-r--r--include/clang/Driver/CC1Options.td24
-rw-r--r--include/clang/Driver/Compilation.h13
-rw-r--r--include/clang/Driver/Driver.h6
-rw-r--r--include/clang/Driver/HostInfo.h2
-rw-r--r--include/clang/Driver/Makefile4
-rw-r--r--include/clang/Driver/OptTable.h3
-rw-r--r--include/clang/Driver/Option.h49
-rw-r--r--include/clang/Driver/Options.td104
-rw-r--r--include/clang/Driver/ToolChain.h9
-rw-r--r--include/clang/Driver/Types.def10
-rw-r--r--include/clang/Driver/Types.h4
-rw-r--r--include/clang/Frontend/ASTConsumers.h16
-rw-r--r--include/clang/Frontend/AnalyzerOptions.h (renamed from include/clang/Frontend/AnalysisConsumer.h)18
-rw-r--r--include/clang/Frontend/CodeGenOptions.h (renamed from include/clang/CodeGen/CodeGenOptions.h)16
-rw-r--r--include/clang/Frontend/CompilerInstance.h7
-rw-r--r--include/clang/Frontend/CompilerInvocation.h4
-rw-r--r--include/clang/Frontend/DiagnosticOptions.h5
-rw-r--r--include/clang/Frontend/FrontendAction.h67
-rw-r--r--include/clang/Frontend/FrontendActions.h54
-rw-r--r--include/clang/Frontend/FrontendOptions.h23
-rw-r--r--include/clang/Frontend/FrontendPluginRegistry.h2
-rw-r--r--include/clang/Frontend/PCHBitCodes.h59
-rw-r--r--include/clang/Frontend/PCHReader.h144
-rw-r--r--include/clang/Frontend/PCHWriter.h54
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h9
-rw-r--r--include/clang/Frontend/TypeXML.def5
-rw-r--r--include/clang/Frontend/Utils.h6
-rw-r--r--include/clang/Index/CallGraph.h4
-rw-r--r--include/clang/Index/Entity.h4
-rw-r--r--include/clang/Index/Indexer.h7
-rw-r--r--include/clang/Index/TranslationUnit.h2
-rw-r--r--include/clang/Lex/PPCallbacks.h12
-rw-r--r--include/clang/Lex/Pragma.h33
-rw-r--r--include/clang/Lex/Preprocessor.h17
-rw-r--r--include/clang/Lex/Token.h8
-rw-r--r--include/clang/Makefile4
-rw-r--r--include/clang/Parse/Action.h305
-rw-r--r--include/clang/Parse/AttributeList.h1
-rw-r--r--include/clang/Parse/DeclSpec.h10
-rw-r--r--include/clang/Parse/Parser.h14
-rw-r--r--include/clang/Parse/Template.h2
-rw-r--r--include/clang/Rewrite/ASTConsumers.h45
-rw-r--r--include/clang/Rewrite/FixItRewriter.h (renamed from include/clang/Frontend/FixItRewriter.h)6
-rw-r--r--include/clang/Rewrite/FrontendActions.h69
-rw-r--r--include/clang/Rewrite/RewriteRope.h1
-rw-r--r--include/clang/Rewrite/Rewriter.h1
-rw-r--r--include/clang/Rewrite/Rewriters.h31
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h24
-rw-r--r--include/clang/Sema/ExternalSemaSource.h2
127 files changed, 6052 insertions, 1853 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 87a12cde2ad2..3799451360f4 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -62,6 +62,7 @@ namespace clang {
class RecordDecl;
class StoredDeclsMap;
class TagDecl;
+ class TemplateTemplateParmDecl;
class TemplateTypeParmDecl;
class TranslationUnitDecl;
class TypeDecl;
@@ -75,6 +76,8 @@ namespace clang {
/// ASTContext - This class holds long-lived AST nodes (such as types and
/// decls) that can be referred to throughout the semantic analysis of a file.
class ASTContext {
+ ASTContext &this_() { return *this; }
+
std::vector<Type*> Types;
llvm::FoldingSet<ExtQuals> ExtQualNodes;
llvm::FoldingSet<ComplexType> ComplexTypes;
@@ -95,9 +98,12 @@ class ASTContext {
llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
- llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
+ llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
+ TemplateSpecializationTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<DependentNameType> DependentNameTypes;
+ llvm::ContextualFoldingSet<DependentTemplateSpecializationType, ASTContext&>
+ DependentTemplateSpecializationTypes;
llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
@@ -122,6 +128,30 @@ class ASTContext {
/// \brief Mapping from ObjCContainers to their ObjCImplementations.
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
+ /// \brief Representation of a "canonical" template template parameter that
+ /// is used in canonical template names.
+ class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
+ TemplateTemplateParmDecl *Parm;
+
+ public:
+ CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
+ : Parm(Parm) { }
+
+ TemplateTemplateParmDecl *getParam() const { return Parm; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); }
+
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ TemplateTemplateParmDecl *Parm);
+ };
+ llvm::FoldingSet<CanonicalTemplateTemplateParm> CanonTemplateTemplateParms;
+
+ TemplateTemplateParmDecl *getCanonicalTemplateTemplateParmDecl(
+ TemplateTemplateParmDecl *TTP);
+
+ /// \brief Whether __[u]int128_t identifier is installed.
+ bool IsInt128Installed;
+
/// BuiltinVaListType - built-in va list type.
/// This is initially null and set by Sema::LazilyCreateBuiltin when
/// a builtin that takes a valist is encountered.
@@ -162,6 +192,8 @@ class ASTContext {
/// \brief Type for the Block descriptor for Blocks CodeGen.
RecordDecl *BlockDescriptorExtendedType;
+ TypeSourceInfo NullTypeSourceInfo;
+
/// \brief Keeps track of all declaration attributes.
///
/// Since so few decls have attrs, we keep them in a hash map instead of
@@ -302,7 +334,8 @@ public:
/// \brief Note that the static data member \p Inst is an instantiation of
/// the static data member template \p Tmpl of a class template.
void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
- TemplateSpecializationKind TSK);
+ TemplateSpecializationKind TSK,
+ SourceLocation PointOfInstantiation = SourceLocation());
/// \brief If the given using decl is an instantiation of a
/// (possibly unresolved) using decl from a template instantiation,
@@ -329,6 +362,8 @@ public:
overridden_cxx_method_iterator
overridden_methods_end(const CXXMethodDecl *Method) const;
+ unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
+
/// \brief Note that the given C++ \p Method overrides the given \p
/// Overridden method.
void addOverriddenMethod(const CXXMethodDecl *Method,
@@ -534,7 +569,7 @@ public:
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts,
- bool AltiVec, bool IsPixel);
+ VectorType::AltiVecSpecific AltiVecSpec);
/// getExtVectorType - Return the unique reference to an extended vector type
/// of the specified element type and size. VectorType must be a built-in
@@ -585,7 +620,11 @@ public:
/// getTypedefType - Return the unique reference to the type for the
/// specified typename decl.
- QualType getTypedefType(const TypedefDecl *Decl);
+ QualType getTypedefType(const TypedefDecl *Decl, QualType Canon = QualType());
+
+ QualType getRecordType(const RecordDecl *Decl);
+
+ QualType getEnumType(const EnumDecl *Decl);
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST);
@@ -599,13 +638,15 @@ public:
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
unsigned NumArgs,
- QualType Canon = QualType(),
- bool IsCurrentInstantiation = false);
+ QualType Canon = QualType());
+
+ QualType getCanonicalTemplateSpecializationType(TemplateName T,
+ const TemplateArgument *Args,
+ unsigned NumArgs);
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgumentListInfo &Args,
- QualType Canon = QualType(),
- bool IsCurrentInstantiation = false);
+ QualType Canon = QualType());
TypeSourceInfo *
getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
@@ -619,10 +660,16 @@ public:
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
QualType Canon = QualType());
- QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const TemplateSpecializationType *TemplateId,
- QualType Canon = QualType());
+
+ QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ const TemplateArgumentListInfo &Args);
+ QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ unsigned NumArgs,
+ const TemplateArgument *Args);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
@@ -780,6 +827,10 @@ public:
/// purpose in characters.
CharUnits getObjCEncodingTypeSize(QualType t);
+ /// \brief Whether __[u]int128_t identifier is installed.
+ bool isInt128Installed() const { return IsInt128Installed; }
+ void setInt128Installed() { IsInt128Installed = true; }
+
/// 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.
QualType getObjCIdType() const { return ObjCIdTypedefType; }
@@ -943,8 +994,9 @@ public:
const ASTRecordLayout &
getASTObjCImplementationLayout(const ObjCImplementationDecl *D);
- /// getKeyFunction - Get the key function for the given record decl.
- /// The key function is, according to the Itanium C++ ABI section 5.2.3:
+ /// getKeyFunction - Get the key function for the given record decl, or NULL
+ /// if there isn't one. The key function is, according to the Itanium C++ ABI
+ /// section 5.2.3:
///
/// ...the first non-pure virtual function that is not inline at the point
/// of class definition.
@@ -1013,6 +1065,8 @@ public:
return UnqualT1 == UnqualT2;
}
+ bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
+
/// \brief Retrieves the "canonical" declaration of
/// \brief Retrieves the "canonical" nested name specifier for a
@@ -1272,6 +1326,8 @@ public:
TypeSourceInfo *
getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation());
+ TypeSourceInfo *getNullTypeSourceInfo() { return &NullTypeSourceInfo; }
+
/// \brief Add a deallocation callback that will be invoked when the
/// ASTContext is destroyed.
///
@@ -1280,6 +1336,38 @@ public:
/// \brief Data Pointer data that will be provided to the callback function
/// when it is called.
void AddDeallocation(void (*Callback)(void*), void *Data);
+
+ //===--------------------------------------------------------------------===//
+ // Statistics
+ //===--------------------------------------------------------------------===//
+
+ /// \brief The number of implicitly-declared default constructors.
+ static unsigned NumImplicitDefaultConstructors;
+
+ /// \brief The number of implicitly-declared default constructors for
+ /// which declarations were built.
+ static unsigned NumImplicitDefaultConstructorsDeclared;
+
+ /// \brief The number of implicitly-declared copy constructors.
+ static unsigned NumImplicitCopyConstructors;
+
+ /// \brief The number of implicitly-declared copy constructors for
+ /// which declarations were built.
+ static unsigned NumImplicitCopyConstructorsDeclared;
+
+ /// \brief The number of implicitly-declared copy assignment operators.
+ static unsigned NumImplicitCopyAssignmentOperators;
+
+ /// \brief The number of implicitly-declared copy assignment operators for
+ /// which declarations were built.
+ static unsigned NumImplicitCopyAssignmentOperatorsDeclared;
+
+ /// \brief The number of implicitly-declared destructors.
+ static unsigned NumImplicitDestructors;
+
+ /// \brief The number of implicitly-declared destructors for which
+ /// declarations were built.
+ static unsigned NumImplicitDestructorsDeclared;
private:
ASTContext(const ASTContext&); // DO NOT IMPLEMENT
@@ -1308,6 +1396,11 @@ private:
// by DeclContext objects. This probably should not be in ASTContext,
// but we include it here so that ASTContext can quickly deallocate them.
llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
+
+ /// \brief A counter used to uniquely identify "blocks".
+ unsigned int UniqueBlockByRefTypeID;
+ unsigned int UniqueBlockParmTypeID;
+
friend class DeclContext;
friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 3240e50b0787..9faa62eef6f7 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -16,6 +16,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/ADT/StringRef.h"
+#include "clang/Basic/AttrKinds.h"
#include <cassert>
#include <cstring>
#include <algorithm>
@@ -25,6 +26,7 @@ namespace clang {
class ASTContext;
class IdentifierInfo;
class ObjCInterfaceDecl;
+ class Expr;
}
// Defined in ASTContext.h
@@ -41,75 +43,9 @@ namespace clang {
/// Attr - This represents one attribute.
class Attr {
-public:
- enum Kind {
- Alias,
- Aligned,
- AlignMac68k,
- AlwaysInline,
- AnalyzerNoReturn, // Clang-specific.
- Annotate,
- AsmLabel, // Represent GCC asm label extension.
- BaseCheck,
- Blocks,
- CDecl,
- Cleanup,
- Const,
- Constructor,
- Deprecated,
- Destructor,
- FastCall,
- Final,
- Format,
- FormatArg,
- GNUInline,
- Hiding,
- IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
- IBOutletCollectionKind, // Clang-specific.
- IBActionKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
- Malloc,
- MaxFieldAlignment,
- NoDebug,
- NoInline,
- NonNull,
- NoReturn,
- NoThrow,
- ObjCException,
- ObjCNSObject,
- Override,
- CFReturnsRetained, // Clang/Checker-specific.
- CFReturnsNotRetained, // Clang/Checker-specific.
- NSReturnsRetained, // Clang/Checker-specific.
- NSReturnsNotRetained, // Clang/Checker-specific.
- Overloadable, // Clang-specific
- Packed,
- Pure,
- Regparm,
- ReqdWorkGroupSize, // OpenCL-specific
- Section,
- Sentinel,
- StdCall,
- ThisCall,
- TransparentUnion,
- Unavailable,
- Unused,
- Used,
- Visibility,
- WarnUnusedResult,
- Weak,
- WeakImport,
- WeakRef,
-
- FIRST_TARGET_ATTRIBUTE,
- DLLExport,
- DLLImport,
- MSP430Interrupt,
- X86ForceAlignArgPointer
- };
-
private:
Attr *Next;
- Kind AttrKind;
+ attr::Kind AttrKind;
bool Inherited : 1;
protected:
@@ -122,7 +58,7 @@ protected:
}
protected:
- Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
+ Attr(attr::Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
virtual ~Attr() {
assert(Next == 0 && "Destroy didn't work");
}
@@ -133,7 +69,7 @@ public:
/// declarations.
virtual bool isMerged() const { return true; }
- Kind getKind() const { return AttrKind; }
+ attr::Kind getKind() const { return AttrKind; }
Attr *getNext() { return Next; }
const Attr *getNext() const { return Next; }
@@ -163,13 +99,15 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *) { return true; }
};
+
+#include "clang/AST/Attrs.inc"
class AttrWithString : public Attr {
private:
const char *Str;
unsigned StrLen;
protected:
- AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s);
+ AttrWithString(attr::Kind AK, ASTContext &C, llvm::StringRef s);
llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
void ReplaceString(ASTContext &C, llvm::StringRef newS);
public:
@@ -179,9 +117,9 @@ public:
#define DEF_SIMPLE_ATTR(ATTR) \
class ATTR##Attr : public Attr { \
public: \
- ATTR##Attr() : Attr(ATTR) {} \
+ ATTR##Attr() : Attr(attr::ATTR) {} \
virtual Attr *clone(ASTContext &C) const; \
- static bool classof(const Attr *A) { return A->getKind() == ATTR; } \
+ static bool classof(const Attr *A) { return A->getKind() == attr::ATTR; } \
static bool classof(const ATTR##Attr *A) { return true; } \
}
@@ -194,7 +132,7 @@ class MaxFieldAlignmentAttr : public Attr {
public:
MaxFieldAlignmentAttr(unsigned alignment)
- : Attr(MaxFieldAlignment), Alignment(alignment) {}
+ : Attr(attr::MaxFieldAlignment), Alignment(alignment) {}
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
@@ -203,36 +141,58 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == MaxFieldAlignment;
+ return A->getKind() == attr::MaxFieldAlignment;
}
static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
};
DEF_SIMPLE_ATTR(AlignMac68k);
+/// \brief Atribute for specifying the alignment of a variable or type.
+///
+/// This node will either contain the precise Alignment (in bits, not bytes!)
+/// or will contain the expression for the alignment attribute in the case of
+/// a dependent expression within a class or function template. At template
+/// instantiation time these are transformed into concrete attributes.
class AlignedAttr : public Attr {
unsigned Alignment;
+ Expr *AlignmentExpr;
public:
AlignedAttr(unsigned alignment)
- : Attr(Aligned), Alignment(alignment) {}
+ : Attr(attr::Aligned), Alignment(alignment), AlignmentExpr(0) {}
+ AlignedAttr(Expr *E)
+ : Attr(attr::Aligned), Alignment(0), AlignmentExpr(E) {}
+
+ /// getAlignmentExpr - Get a dependent alignment expression if one is present.
+ Expr *getAlignmentExpr() const {
+ return AlignmentExpr;
+ }
+
+ /// isDependent - Is the alignment a dependent expression
+ bool isDependent() const {
+ return getAlignmentExpr();
+ }
+
+ /// getAlignment - The specified alignment in bits. Requires !isDependent().
+ unsigned getAlignment() const {
+ assert(!isDependent() && "Cannot get a value dependent alignment");
+ return Alignment;
+ }
- /// getAlignment - The specified alignment in bits.
- unsigned getAlignment() const { return Alignment; }
-
/// getMaxAlignment - Get the maximum alignment of attributes on this list.
unsigned getMaxAlignment() const {
const AlignedAttr *Next = getNext<AlignedAttr>();
if (Next)
- return std::max(Next->getMaxAlignment(), Alignment);
+ return std::max(Next->getMaxAlignment(), getAlignment());
else
- return Alignment;
+ return getAlignment();
}
virtual Attr* clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == Aligned;
+ return A->getKind() == attr::Aligned;
}
static bool classof(const AlignedAttr *A) { return true; }
};
@@ -240,7 +200,7 @@ public:
class AnnotateAttr : public AttrWithString {
public:
AnnotateAttr(ASTContext &C, llvm::StringRef ann)
- : AttrWithString(Annotate, C, ann) {}
+ : AttrWithString(attr::Annotate, C, ann) {}
llvm::StringRef getAnnotation() const { return getString(); }
@@ -248,7 +208,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == Annotate;
+ return A->getKind() == attr::Annotate;
}
static bool classof(const AnnotateAttr *A) { return true; }
};
@@ -256,7 +216,7 @@ public:
class AsmLabelAttr : public AttrWithString {
public:
AsmLabelAttr(ASTContext &C, llvm::StringRef L)
- : AttrWithString(AsmLabel, C, L) {}
+ : AttrWithString(attr::AsmLabel, C, L) {}
llvm::StringRef getLabel() const { return getString(); }
@@ -264,7 +224,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == AsmLabel;
+ return A->getKind() == attr::AsmLabel;
}
static bool classof(const AsmLabelAttr *A) { return true; }
};
@@ -274,54 +234,56 @@ DEF_SIMPLE_ATTR(AlwaysInline);
class AliasAttr : public AttrWithString {
public:
AliasAttr(ASTContext &C, llvm::StringRef aliasee)
- : AttrWithString(Alias, C, aliasee) {}
+ : AttrWithString(attr::Alias, C, aliasee) {}
llvm::StringRef getAliasee() const { return getString(); }
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Alias; }
+ static bool classof(const Attr *A) { return A->getKind() == attr::Alias; }
static bool classof(const AliasAttr *A) { return true; }
};
class ConstructorAttr : public Attr {
int priority;
public:
- ConstructorAttr(int p) : Attr(Constructor), priority(p) {}
+ ConstructorAttr(int p) : Attr(attr::Constructor), priority(p) {}
int getPriority() const { return priority; }
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Constructor; }
+ static bool classof(const Attr *A)
+ { return A->getKind() == attr::Constructor; }
static bool classof(const ConstructorAttr *A) { return true; }
};
class DestructorAttr : public Attr {
int priority;
public:
- DestructorAttr(int p) : Attr(Destructor), priority(p) {}
+ DestructorAttr(int p) : Attr(attr::Destructor), priority(p) {}
int getPriority() const { return priority; }
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Destructor; }
+ static bool classof(const Attr *A)
+ { return A->getKind() == attr::Destructor; }
static bool classof(const DestructorAttr *A) { return true; }
};
class IBOutletAttr : public Attr {
public:
- IBOutletAttr() : Attr(IBOutletKind) {}
+ IBOutletAttr() : Attr(attr::IBOutlet) {}
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == IBOutletKind;
+ return A->getKind() == attr::IBOutlet;
}
static bool classof(const IBOutletAttr *A) { return true; }
};
@@ -330,7 +292,7 @@ class IBOutletCollectionAttr : public Attr {
const ObjCInterfaceDecl *D;
public:
IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0)
- : Attr(IBOutletCollectionKind), D(d) {}
+ : Attr(attr::IBOutletCollection), D(d) {}
const ObjCInterfaceDecl *getClass() const { return D; }
@@ -338,35 +300,35 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == IBOutletCollectionKind;
+ return A->getKind() == attr::IBOutletCollection;
}
static bool classof(const IBOutletCollectionAttr *A) { return true; }
};
class IBActionAttr : public Attr {
public:
- IBActionAttr() : Attr(IBActionKind) {}
+ IBActionAttr() : Attr(attr::IBAction) {}
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == IBActionKind;
+ return A->getKind() == attr::IBAction;
}
static bool classof(const IBActionAttr *A) { return true; }
};
DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
-DEF_SIMPLE_ATTR(Final);
DEF_SIMPLE_ATTR(GNUInline);
DEF_SIMPLE_ATTR(Malloc);
DEF_SIMPLE_ATTR(NoReturn);
+DEF_SIMPLE_ATTR(NoInstrumentFunction);
class SectionAttr : public AttrWithString {
public:
SectionAttr(ASTContext &C, llvm::StringRef N)
- : AttrWithString(Section, C, N) {}
+ : AttrWithString(attr::Section, C, N) {}
llvm::StringRef getName() const { return getString(); }
@@ -374,7 +336,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == Section;
+ return A->getKind() == attr::Section;
}
static bool classof(const SectionAttr *A) { return true; }
};
@@ -408,7 +370,7 @@ public:
virtual Attr *clone(ASTContext &C) const;
- static bool classof(const Attr *A) { return A->getKind() == NonNull; }
+ static bool classof(const Attr *A) { return A->getKind() == attr::NonNull; }
static bool classof(const NonNullAttr *A) { return true; }
};
@@ -416,7 +378,7 @@ class FormatAttr : public AttrWithString {
int formatIdx, firstArg;
public:
FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
- : AttrWithString(Format, C, type), formatIdx(idx), firstArg(first) {}
+ : AttrWithString(attr::Format, C, type), formatIdx(idx), firstArg(first) {}
llvm::StringRef getType() const { return getString(); }
void setType(ASTContext &C, llvm::StringRef type);
@@ -426,27 +388,27 @@ public:
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Format; }
+ static bool classof(const Attr *A) { return A->getKind() == attr::Format; }
static bool classof(const FormatAttr *A) { return true; }
};
class FormatArgAttr : public Attr {
int formatIdx;
public:
- FormatArgAttr(int idx) : Attr(FormatArg), formatIdx(idx) {}
+ FormatArgAttr(int idx) : Attr(attr::FormatArg), formatIdx(idx) {}
int getFormatIdx() const { return formatIdx; }
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == FormatArg; }
+ static bool classof(const Attr *A) { return A->getKind() == attr::FormatArg; }
static bool classof(const FormatArgAttr *A) { return true; }
};
class SentinelAttr : public Attr {
int sentinel, NullPos;
public:
- SentinelAttr(int sentinel_val, int nullPos) : Attr(Sentinel),
+ SentinelAttr(int sentinel_val, int nullPos) : Attr(attr::Sentinel),
sentinel(sentinel_val), NullPos(nullPos) {}
int getSentinel() const { return sentinel; }
int getNullPos() const { return NullPos; }
@@ -454,7 +416,7 @@ public:
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Sentinel; }
+ static bool classof(const Attr *A) { return A->getKind() == attr::Sentinel; }
static bool classof(const SentinelAttr *A) { return true; }
};
@@ -469,7 +431,7 @@ public:
private:
VisibilityTypes VisibilityType;
public:
- VisibilityAttr(VisibilityTypes v) : Attr(Visibility),
+ VisibilityAttr(VisibilityTypes v) : Attr(attr::Visibility),
VisibilityType(v) {}
VisibilityTypes getVisibility() const { return VisibilityType; }
@@ -477,7 +439,8 @@ public:
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 Attr *A)
+ { return A->getKind() == attr::Visibility; }
static bool classof(const VisibilityAttr *A) { return true; }
};
@@ -491,13 +454,14 @@ DEF_SIMPLE_ATTR(ObjCException);
class OverloadableAttr : public Attr {
public:
- OverloadableAttr() : Attr(Overloadable) { }
+ OverloadableAttr() : Attr(attr::Overloadable) { }
virtual bool isMerged() const { return false; }
virtual Attr *clone(ASTContext &C) const;
- static bool classof(const Attr *A) { return A->getKind() == Overloadable; }
+ static bool classof(const Attr *A)
+ { return A->getKind() == attr::Overloadable; }
static bool classof(const OverloadableAttr *) { return true; }
};
@@ -509,14 +473,14 @@ public:
private:
BlocksAttrTypes BlocksAttrType;
public:
- BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {}
+ BlocksAttr(BlocksAttrTypes t) : Attr(attr::Blocks), BlocksAttrType(t) {}
BlocksAttrTypes getType() const { return BlocksAttrType; }
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Blocks; }
+ static bool classof(const Attr *A) { return A->getKind() == attr::Blocks; }
static bool classof(const BlocksAttr *A) { return true; }
};
@@ -526,14 +490,14 @@ class CleanupAttr : public Attr {
FunctionDecl *FD;
public:
- CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {}
+ CleanupAttr(FunctionDecl *fd) : Attr(attr::Cleanup), FD(fd) {}
const FunctionDecl *getFunctionDecl() const { return FD; }
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
+ static bool classof(const Attr *A) { return A->getKind() == attr::Cleanup; }
static bool classof(const CleanupAttr *A) { return true; }
};
@@ -545,14 +509,14 @@ class RegparmAttr : public Attr {
unsigned NumParams;
public:
- RegparmAttr(unsigned np) : Attr(Regparm), NumParams(np) {}
+ RegparmAttr(unsigned np) : Attr(attr::Regparm), NumParams(np) {}
unsigned getNumParams() const { return NumParams; }
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Regparm; }
+ static bool classof(const Attr *A) { return A->getKind() == attr::Regparm; }
static bool classof(const RegparmAttr *A) { return true; }
};
@@ -560,7 +524,7 @@ class ReqdWorkGroupSizeAttr : public Attr {
unsigned X, Y, Z;
public:
ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
- : Attr(ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
+ : Attr(attr::ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
unsigned getXDim() const { return X; }
unsigned getYDim() const { return Y; }
@@ -570,22 +534,34 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == ReqdWorkGroupSize;
+ return A->getKind() == attr::ReqdWorkGroupSize;
}
static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
};
+class InitPriorityAttr : public Attr {
+ unsigned Priority;
+public:
+ InitPriorityAttr(unsigned priority)
+ : Attr(attr::InitPriority), Priority(priority) {}
+
+ virtual void Destroy(ASTContext &C) { Attr::Destroy(C); }
+
+ unsigned getPriority() const { return Priority; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ static bool classof(const Attr *A)
+ { return A->getKind() == attr::InitPriority; }
+ static bool classof(const InitPriorityAttr *A) { return true; }
+};
+
// Checker-specific attributes.
DEF_SIMPLE_ATTR(CFReturnsNotRetained);
DEF_SIMPLE_ATTR(CFReturnsRetained);
DEF_SIMPLE_ATTR(NSReturnsNotRetained);
DEF_SIMPLE_ATTR(NSReturnsRetained);
-// C++0x member checking attributes.
-DEF_SIMPLE_ATTR(BaseCheck);
-DEF_SIMPLE_ATTR(Hiding);
-DEF_SIMPLE_ATTR(Override);
-
// Target-specific attributes
DEF_SIMPLE_ATTR(DLLImport);
DEF_SIMPLE_ATTR(DLLExport);
@@ -594,14 +570,15 @@ class MSP430InterruptAttr : public Attr {
unsigned Number;
public:
- MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {}
+ MSP430InterruptAttr(unsigned n) : Attr(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 Attr *A)
+ { return A->getKind() == attr::MSP430Interrupt; }
static bool classof(const MSP430InterruptAttr *A) { return true; }
};
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index c24ea06aa024..3b090715e083 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -1,5 +1,18 @@
-set(LLVM_TARGET_DEFINITIONS StmtNodes.td)
+set(LLVM_TARGET_DEFINITIONS ../Basic/Attr.td)
+tablegen(Attrs.inc
+ -gen-clang-attr-classes
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrClasses
+ DEPENDS Attrs.inc)
+
+set(LLVM_TARGET_DEFINITIONS ../Basic/StmtNodes.td)
tablegen(StmtNodes.inc
-gen-clang-stmt-nodes)
add_custom_target(ClangStmtNodes
DEPENDS StmtNodes.inc)
+
+set(LLVM_TARGET_DEFINITIONS ../Basic/DeclNodes.td)
+tablegen(DeclNodes.inc
+ -gen-clang-decl-nodes)
+add_custom_target(ClangDeclNodes
+ DEPENDS DeclNodes.inc)
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 4afb81dd05eb..9f97fd8a7aee 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -247,6 +247,7 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
@@ -269,8 +270,10 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 7d5b66e02a28..39cd51f606b5 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -28,6 +28,8 @@ class FunctionTemplateDecl;
class Stmt;
class CompoundStmt;
class StringLiteral;
+class NestedNameSpecifier;
+class TemplateParameterList;
class TemplateArgumentList;
class MemberSpecializationInfo;
class FunctionTemplateSpecializationInfo;
@@ -216,7 +218,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamedDecl *D) { return true; }
- static bool classofKind(Kind K) { return K >= NamedFirst && K <= NamedLast; }
+ static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
};
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
@@ -342,6 +344,9 @@ public:
static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
}
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// ValueDecl - Represent the declaration of a variable (in which case it is
@@ -361,7 +366,38 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ValueDecl *D) { return true; }
- static bool classofKind(Kind K) { return K >= ValueFirst && K <= ValueLast; }
+ static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
+};
+
+/// QualifierInfo - A struct with extended info about a syntactic
+/// name qualifier, to be used for the case of out-of-line declarations.
+struct QualifierInfo {
+ /// NNS - The syntactic name qualifier.
+ NestedNameSpecifier *NNS;
+ /// NNSRange - The source range for the qualifier.
+ SourceRange NNSRange;
+ /// NumTemplParamLists - The number of template parameter lists
+ /// that were matched against the template-ids occurring into the NNS.
+ unsigned NumTemplParamLists;
+ /// TemplParamLists - A new-allocated array of size NumTemplParamLists,
+ /// containing pointers to the matched template parameter lists.
+ TemplateParameterList** TemplParamLists;
+
+ /// Default constructor.
+ QualifierInfo()
+ : NNS(0), NNSRange(), NumTemplParamLists(0), TemplParamLists(0) {}
+ /// setTemplateParameterListsInfo - Sets info about matched template
+ /// parameter lists.
+ void setTemplateParameterListsInfo(ASTContext &Context,
+ unsigned NumTPLists,
+ TemplateParameterList **TPLists);
+
+ void Destroy(ASTContext &Context);
+
+private:
+ // Copy constructor and copy assignment are disabled.
+ QualifierInfo(const QualifierInfo&);
+ QualifierInfo& operator=(const QualifierInfo&);
};
/// \brief Represents a ValueDecl that came out of a declarator.
@@ -369,10 +405,8 @@ public:
class DeclaratorDecl : public ValueDecl {
// A struct representing both a TInfo and a syntactic qualifier,
// to be used for the (uncommon) case of out-of-line declarations.
- struct ExtInfo {
+ struct ExtInfo : public QualifierInfo {
TypeSourceInfo *TInfo;
- NestedNameSpecifier *NNS;
- SourceRange NNSRange;
};
llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
@@ -392,32 +426,55 @@ public:
TypeSourceInfo *getTypeSourceInfo() const {
return hasExtInfo()
- ? DeclInfo.get<ExtInfo*>()->TInfo
+ ? getExtInfo()->TInfo
: DeclInfo.get<TypeSourceInfo*>();
}
void setTypeSourceInfo(TypeSourceInfo *TI) {
if (hasExtInfo())
- DeclInfo.get<ExtInfo*>()->TInfo = TI;
+ getExtInfo()->TInfo = TI;
else
DeclInfo = TI;
}
+ /// getInnerLocStart - Return SourceLocation representing start of source
+ /// range ignoring outer template declarations.
+ virtual SourceLocation getInnerLocStart() const { return getLocation(); }
+
+ /// getOuterLocStart - Return SourceLocation representing start of source
+ /// range taking into account any outer template declarations.
+ SourceLocation getOuterLocStart() const;
+ SourceRange getSourceRange() const {
+ return SourceRange(getOuterLocStart(), getLocation());
+ }
+
NestedNameSpecifier *getQualifier() const {
- return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNS : 0;
+ return hasExtInfo() ? getExtInfo()->NNS : 0;
}
SourceRange getQualifierRange() const {
- return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNSRange : SourceRange();
+ return hasExtInfo() ? getExtInfo()->NNSRange : SourceRange();
}
void setQualifierInfo(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange);
+ unsigned getNumTemplateParameterLists() const {
+ return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
+ }
+ TemplateParameterList *getTemplateParameterList(unsigned index) const {
+ assert(index < getNumTemplateParameterLists());
+ return getExtInfo()->TemplParamLists[index];
+ }
+ void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
+ TemplateParameterList **TPLists) {
+ getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
+ }
+
SourceLocation getTypeSpecStartLoc() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const DeclaratorDecl *D) { return true; }
static bool classofKind(Kind K) {
- return K >= DeclaratorFirst && K <= DeclaratorLast;
+ return K >= firstDeclarator && K <= lastDeclarator;
}
};
@@ -555,6 +612,7 @@ public:
virtual void Destroy(ASTContext& C);
virtual ~VarDecl();
+ virtual SourceLocation getInnerLocStart() const;
virtual SourceRange getSourceRange() const;
StorageClass getStorageClass() const { return (StorageClass)SClass; }
@@ -908,7 +966,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const VarDecl *D) { return true; }
- static bool classofKind(Kind K) { return K >= VarFirst && K <= VarLast; }
+ static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
};
class ImplicitParamDecl : public VarDecl {
@@ -1063,6 +1121,15 @@ public:
None, Extern, Static, PrivateExtern
};
+ /// \brief The kind of templated function a FunctionDecl can be.
+ enum TemplatedKind {
+ TK_NonTemplate,
+ TK_FunctionTemplate,
+ TK_MemberSpecialization,
+ TK_FunctionTemplateSpecialization,
+ TK_DependentFunctionTemplateSpecialization
+ };
+
private:
/// ParamInfo - new[]'d array of pointers to VarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
@@ -1154,17 +1221,31 @@ public:
bool Qualified) const;
virtual SourceRange getSourceRange() const {
- return SourceRange(getLocation(), EndRangeLoc);
+ return SourceRange(getOuterLocStart(), EndRangeLoc);
}
void setLocEnd(SourceLocation E) {
EndRangeLoc = E;
}
+ /// \brief Returns true if the function has a body (definition). The
+ /// function body might be in any of the (re-)declarations of this
+ /// function. The variant that accepts a FunctionDecl pointer will
+ /// set that function declaration to the actual declaration
+ /// containing the body (if there is one).
+ bool hasBody(const FunctionDecl *&Definition) const;
+
+ virtual bool hasBody() const {
+ const FunctionDecl* Definition;
+ return hasBody(Definition);
+ }
+
/// getBody - Retrieve the body (definition) of the function. The
/// function body might be in any of the (re-)declarations of this
/// function. The variant that accepts a FunctionDecl pointer will
/// set that function declaration to the actual declaration
/// containing the body (if there is one).
+ /// NOTE: For checking if there is a body, use hasBody() instead, to avoid
+ /// unnecessary PCH de-serialization of the body.
Stmt *getBody(const FunctionDecl *&Definition) const;
virtual Stmt *getBody() const {
@@ -1301,6 +1382,12 @@ public:
QualType getResultType() const {
return getType()->getAs<FunctionType>()->getResultType();
}
+
+ /// \brief Determine the type of an expression that calls this function.
+ QualType getCallResultType() const {
+ return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
+ }
+
StorageClass getStorageClass() const { return StorageClass(SClass); }
void setStorageClass(StorageClass SC) { SClass = SC; }
@@ -1355,6 +1442,9 @@ public:
/// X<int>::A is required, it will be instantiated from the
/// declaration returned by getInstantiatedFromMemberFunction().
FunctionDecl *getInstantiatedFromMemberFunction() const;
+
+ /// \brief What kind of templated function this is.
+ TemplatedKind getTemplatedKind() const;
/// \brief If this function is an instantiation of a member function of a
/// class template specialization, retrieves the member specialization
@@ -1437,8 +1527,6 @@ public:
/// \brief Specify that this function declaration is actually a function
/// template specialization.
///
- /// \param Context the AST context in which this function resides.
- ///
/// \param Template the function template that this function template
/// specialization specializes.
///
@@ -1450,11 +1538,53 @@ public:
/// be inserted.
///
/// \param TSK the kind of template specialization this is.
+ ///
+ /// \param TemplateArgsAsWritten location info of template arguments.
+ ///
+ /// \param PointOfInstantiation point at which the function template
+ /// specialization was first instantiated.
void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
void *InsertPos,
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
- const TemplateArgumentListInfo *TemplateArgsAsWritten = 0);
+ const TemplateArgumentListInfo *TemplateArgsAsWritten = 0,
+ SourceLocation PointOfInstantiation = SourceLocation());
+
+ /// \brief Specify that this function declaration is actually a function
+ /// template specialization.
+ ///
+ /// \param Template the function template that this function template
+ /// specialization specializes.
+ ///
+ /// \param NumTemplateArgs number of template arguments that produced this
+ /// function template specialization from the template.
+ ///
+ /// \param TemplateArgs array of template arguments that produced this
+ /// function template specialization from the template.
+ ///
+ /// \param TSK the kind of template specialization this is.
+ ///
+ /// \param NumTemplateArgsAsWritten number of template arguments that produced
+ /// this function template specialization from the template.
+ ///
+ /// \param TemplateArgsAsWritten array of location info for the template
+ /// arguments.
+ ///
+ /// \param LAngleLoc location of left angle token.
+ ///
+ /// \param RAngleLoc location of right angle token.
+ ///
+ /// \param PointOfInstantiation point at which the function template
+ /// specialization was first instantiated.
+ void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
+ unsigned NumTemplateArgs,
+ const TemplateArgument *TemplateArgs,
+ TemplateSpecializationKind TSK,
+ unsigned NumTemplateArgsAsWritten,
+ TemplateArgumentLoc *TemplateArgsAsWritten,
+ SourceLocation LAngleLoc,
+ SourceLocation RAngleLoc,
+ SourceLocation PointOfInstantiation);
/// \brief Specifies that this function declaration is actually a
/// dependent function template specialization.
@@ -1493,7 +1623,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionDecl *D) { return true; }
static bool classofKind(Kind K) {
- return K >= FunctionFirst && K <= FunctionLast;
+ return K >= firstFunction && K <= lastFunction;
}
static DeclContext *castToDeclContext(const FunctionDecl *D) {
return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
@@ -1501,6 +1631,9 @@ public:
static FunctionDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
}
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
@@ -1556,7 +1689,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FieldDecl *D) { return true; }
- static bool classofKind(Kind K) { return K >= FieldFirst && K <= FieldLast; }
+ static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
};
/// EnumConstantDecl - An instance of this object exists for each enum constant
@@ -1625,7 +1758,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypeDecl *D) { return true; }
- static bool classofKind(Kind K) { return K >= TypeFirst && K <= TypeLast; }
+ static bool classofKind(Kind K) { return K >= firstType && K <= lastType; }
};
@@ -1715,10 +1848,7 @@ private:
// A struct representing syntactic qualifier info,
// to be used for the (uncommon) case of out-of-line declarations.
- struct ExtInfo {
- NestedNameSpecifier *NNS;
- SourceRange NNSRange;
- };
+ typedef QualifierInfo ExtInfo;
/// TypedefDeclOrQualifier - If the (out-of-line) tag declaration name
/// is qualified, it points to the qualifier info (nns and range);
@@ -1767,6 +1897,13 @@ public:
SourceLocation getTagKeywordLoc() const { return TagKeywordLoc; }
void setTagKeywordLoc(SourceLocation TKL) { TagKeywordLoc = TKL; }
+ /// getInnerLocStart - Return SourceLocation representing start of source
+ /// range ignoring outer template declarations.
+ virtual SourceLocation getInnerLocStart() const { return TagKeywordLoc; }
+
+ /// getOuterLocStart - Return SourceLocation representing start of source
+ /// range taking into account any outer template declarations.
+ SourceLocation getOuterLocStart() const;
virtual SourceRange getSourceRange() const;
virtual TagDecl* getCanonicalDecl();
@@ -1830,24 +1967,34 @@ public:
TypedefDecl *getTypedefForAnonDecl() const {
return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
}
-
+
void setTypedefForAnonDecl(TypedefDecl *TDD);
-
+
NestedNameSpecifier *getQualifier() const {
- return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNS : 0;
+ return hasExtInfo() ? getExtInfo()->NNS : 0;
}
SourceRange getQualifierRange() const {
- return hasExtInfo()
- ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNSRange
- : SourceRange();
+ return hasExtInfo() ? getExtInfo()->NNSRange : SourceRange();
}
void setQualifierInfo(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange);
+ unsigned getNumTemplateParameterLists() const {
+ return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
+ }
+ TemplateParameterList *getTemplateParameterList(unsigned i) const {
+ assert(i < getNumTemplateParameterLists());
+ return getExtInfo()->TemplParamLists[i];
+ }
+ void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
+ TemplateParameterList **TPLists) {
+ getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TagDecl *D) { return true; }
- static bool classofKind(Kind K) { return K >= TagFirst && K <= TagLast; }
+ static bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; }
static DeclContext *castToDeclContext(const TagDecl *D) {
return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
@@ -1855,6 +2002,9 @@ public:
static TagDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
}
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
@@ -1896,9 +2046,17 @@ public:
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
}
+ const EnumDecl *getPreviousDeclaration() const {
+ return cast_or_null<EnumDecl>(TagDecl::getPreviousDeclaration());
+ }
+ EnumDecl *getPreviousDeclaration() {
+ return cast_or_null<EnumDecl>(TagDecl::getPreviousDeclaration());
+ }
+
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL, EnumDecl *PrevDecl);
+ static EnumDecl *Create(ASTContext &C, EmptyShell Empty);
virtual void Destroy(ASTContext& C);
@@ -1917,11 +2075,17 @@ public:
typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
enumerator_iterator enumerator_begin() const {
- return enumerator_iterator(this->decls_begin());
+ const EnumDecl *E = cast_or_null<EnumDecl>(getDefinition());
+ if (!E)
+ E = this;
+ return enumerator_iterator(E->decls_begin());
}
enumerator_iterator enumerator_end() const {
- return enumerator_iterator(this->decls_end());
+ const EnumDecl *E = cast_or_null<EnumDecl>(getDefinition());
+ if (!E)
+ E = this;
+ return enumerator_iterator(E->decls_end());
}
/// getPromotionType - Return the integer type that enumerators
@@ -2010,6 +2174,14 @@ public:
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation(),
RecordDecl* PrevDecl = 0);
+ static RecordDecl *Create(ASTContext &C, EmptyShell Empty);
+
+ const RecordDecl *getPreviousDeclaration() const {
+ return cast_or_null<RecordDecl>(TagDecl::getPreviousDeclaration());
+ }
+ RecordDecl *getPreviousDeclaration() {
+ return cast_or_null<RecordDecl>(TagDecl::getPreviousDeclaration());
+ }
virtual void Destroy(ASTContext& C);
@@ -2092,7 +2264,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const RecordDecl *D) { return true; }
static bool classofKind(Kind K) {
- return K >= RecordFirst && K <= RecordLast;
+ return K >= firstRecord && K <= lastRecord;
}
};
@@ -2127,11 +2299,13 @@ class BlockDecl : public Decl, public DeclContext {
unsigned NumParams;
Stmt *Body;
+ TypeSourceInfo *SignatureAsWritten;
protected:
BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
: Decl(Block, DC, CaretLoc), DeclContext(Block),
- IsVariadic(false), ParamInfo(0), NumParams(0), Body(0) {}
+ IsVariadic(false), ParamInfo(0), NumParams(0), Body(0),
+ SignatureAsWritten(0) {}
virtual ~BlockDecl();
virtual void Destroy(ASTContext& C);
@@ -2148,6 +2322,9 @@ public:
Stmt *getBody() const { return (Stmt*) Body; }
void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
+ void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
+ TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; }
+
// Iterator access to formal parameters.
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index c15aeef14ba6..2d2407ffb18d 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -68,12 +68,13 @@ class Decl {
public:
/// \brief Lists the kind of concrete classes of Decl.
enum Kind {
-#define DECL(Derived, Base) Derived,
-#define DECL_RANGE(CommonBase, Start, End) \
- CommonBase##First = Start, CommonBase##Last = End,
-#define LAST_DECL_RANGE(CommonBase, Start, End) \
- CommonBase##First = Start, CommonBase##Last = End
-#include "clang/AST/DeclNodes.def"
+#define DECL(DERIVED, BASE) DERIVED,
+#define ABSTRACT_DECL(DECL)
+#define DECL_RANGE(BASE, START, END) \
+ first##BASE = START, last##BASE = END,
+#define LAST_DECL_RANGE(BASE, START, END) \
+ first##BASE = START, last##BASE = END
+#include "clang/AST/DeclNodes.inc"
};
/// \brief A placeholder type used to construct an empty shell of a
@@ -244,7 +245,15 @@ protected:
HasAttrs(false), Implicit(false), Used(false),
Access(AS_none), PCHLevel(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
- if (Decl::CollectingStats()) addDeclKind(DK);
+ if (Decl::CollectingStats()) add(DK);
+ }
+
+ Decl(Kind DK, EmptyShell Empty)
+ : NextDeclInContext(0), DeclKind(DK), InvalidDecl(0),
+ HasAttrs(false), Implicit(false), Used(false),
+ Access(AS_none), PCHLevel(0),
+ IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
+ if (Decl::CollectingStats()) add(DK);
}
virtual ~Decl();
@@ -296,6 +305,7 @@ public:
}
bool hasAttrs() const { return HasAttrs; }
+ void initAttrs(Attr *attrs);
void addAttr(Attr *attr);
const Attr *getAttrs() const {
if (!HasAttrs) return 0; // common case, no attributes.
@@ -328,7 +338,11 @@ public:
/// \brief Whether this declaration was used, meaning that a definition
/// is required.
- bool isUsed() const;
+ ///
+ /// \param CheckUsedAttr When true, also consider the "used" attribute
+ /// (in addition to the "used" bit set by \c setUsed()) when determining
+ /// whether the function is used.
+ bool isUsed(bool CheckUsedAttr = true) const;
void setUsed(bool U = true) { Used = U; }
@@ -474,15 +488,16 @@ public:
/// top-level Stmt* of that body. Otherwise this method returns null.
virtual Stmt* getBody() const { return 0; }
- /// getCompoundBody - Returns getBody(), dyn_casted to a CompoundStmt.
- CompoundStmt* getCompoundBody() const;
+ /// \brief Returns true if this Decl represents a declaration for a body of
+ /// code, such as a function or method definition.
+ virtual bool hasBody() const { return getBody() != 0; }
/// getBodyRBrace - Gets the right brace of the body, if a body exists.
/// This works whether the body is a CompoundStmt or a CXXTryStmt.
SourceLocation getBodyRBrace() const;
// global temp stats (until we have a per-module visitor)
- static void addDeclKind(Kind k);
+ static void add(Kind k);
static bool CollectingStats(bool Enable = false);
static void PrintStats();
@@ -631,6 +646,8 @@ class DeclContext {
/// another pointer.
mutable Decl *LastDecl;
+ friend class ExternalASTSource;
+
protected:
DeclContext(Decl::Kind K)
: DeclKind(K), ExternalLexicalStorage(false),
@@ -687,7 +704,7 @@ public:
case Decl::ObjCMethod:
return true;
default:
- return DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast;
+ return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction;
}
}
@@ -700,7 +717,7 @@ public:
}
bool isRecord() const {
- return DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast;
+ return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord;
}
bool isNamespace() const {
@@ -1083,9 +1100,10 @@ public:
static bool classof(const Decl *D);
static bool classof(const DeclContext *D) { return true; }
-#define DECL_CONTEXT(Name) \
- static bool classof(const Name##Decl *D) { return true; }
-#include "clang/AST/DeclNodes.def"
+#define DECL(NAME, BASE)
+#define DECL_CONTEXT(NAME) \
+ static bool classof(const NAME##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
void dumpDeclContext() const;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index c19c200f265d..41474ab21e32 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -92,6 +92,53 @@ namespace llvm {
namespace clang {
+/// AccessSpecDecl - An access specifier followed by colon ':'.
+///
+/// An objects of this class represents sugar for the syntactic occurrence
+/// of an access specifier followed by a colon in the list of member
+/// specifiers of a C++ class definition.
+///
+/// Note that they do not represent other uses of access specifiers,
+/// such as those occurring in a list of base specifiers.
+/// Also note that this class has nothing to do with so-called
+/// "access declarations" (C++98 11.3 [class.access.dcl]).
+class AccessSpecDecl : public Decl {
+ /// ColonLoc - The location of the ':'.
+ SourceLocation ColonLoc;
+
+ AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
+ SourceLocation ASLoc, SourceLocation ColonLoc)
+ : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
+ setAccess(AS);
+ }
+public:
+ /// getAccessSpecifierLoc - The location of the access specifier.
+ SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
+ /// setAccessSpecifierLoc - Sets the location of the access specifier.
+ void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
+
+ /// getColonLoc - The location of the colon following the access specifier.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+ /// setColonLoc - Sets the location of the colon.
+ void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(getAccessSpecifierLoc(), getColonLoc());
+ }
+
+ static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
+ DeclContext *DC, SourceLocation ASLoc,
+ SourceLocation ColonLoc) {
+ return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const AccessSpecDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == AccessSpec; }
+};
+
+
/// CXXBaseSpecifier - A base class of a C++ class.
///
/// Each CXXBaseSpecifier represents a single, direct base class (or
@@ -271,7 +318,20 @@ class CXXRecordDecl : public RecordDecl {
/// ComputedVisibleConversions - True when visible conversion functions are
/// already computed and are available.
bool ComputedVisibleConversions : 1;
-
+
+ /// \brief Whether we have already declared the default constructor or
+ /// do not need to have one declared.
+ bool DeclaredDefaultConstructor : 1;
+
+ /// \brief Whether we have already declared the copy constructor.
+ bool DeclaredCopyConstructor : 1;
+
+ /// \brief Whether we have already declared the copy-assignment operator.
+ bool DeclaredCopyAssignment : 1;
+
+ /// \brief Whether we have already declared a destructor within the class.
+ bool DeclaredDestructor : 1;
+
/// Bases - Base classes of this class.
/// FIXME: This is wasted space for a union.
CXXBaseSpecifier *Bases;
@@ -367,6 +427,13 @@ public:
virtual const CXXRecordDecl *getCanonicalDecl() const {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
+
+ const CXXRecordDecl *getPreviousDeclaration() const {
+ return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration());
+ }
+ CXXRecordDecl *getPreviousDeclaration() {
+ return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration());
+ }
CXXRecordDecl *getDefinition() const {
if (!DefinitionData) return 0;
@@ -380,6 +447,7 @@ public:
SourceLocation TKL = SourceLocation(),
CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false);
+ static CXXRecordDecl *Create(ASTContext &C, EmptyShell Empty);
virtual void Destroy(ASTContext& C);
@@ -476,6 +544,20 @@ public:
return data().FirstFriend != 0;
}
+ /// \brief Determine whether this class has had its default constructor
+ /// declared implicitly or does not need one declared implicitly.
+ ///
+ /// This value is used for lazy creation of default constructors.
+ bool hasDeclaredDefaultConstructor() const {
+ return data().DeclaredDefaultConstructor;
+ }
+
+ /// \brief Note whether this class has already had its default constructor
+ /// implicitly declared or doesn't need one.
+ void setDeclaredDefaultConstructor(bool DDC) {
+ data().DeclaredDefaultConstructor = DDC;
+ }
+
/// hasConstCopyConstructor - Determines whether this class has a
/// copy constructor that accepts a const-qualified argument.
bool hasConstCopyConstructor(ASTContext &Context) const;
@@ -484,12 +566,18 @@ public:
CXXConstructorDecl *getCopyConstructor(ASTContext &Context,
unsigned TypeQuals) const;
- /// hasConstCopyAssignment - Determines whether this class has a
- /// copy assignment operator that accepts a const-qualified argument.
- /// It returns its decl in MD if found.
- bool hasConstCopyAssignment(ASTContext &Context,
- const CXXMethodDecl *&MD) const;
-
+ /// \brief Retrieve the copy-assignment operator for this class, if available.
+ ///
+ /// This routine attempts to find the copy-assignment operator for this
+ /// class, using a simplistic form of overload resolution.
+ ///
+ /// \param ArgIsConst Whether the argument to the copy-assignment operator
+ /// is const-qualified.
+ ///
+ /// \returns The copy-assignment operator that can be invoked, or NULL if
+ /// a unique copy-assignment operator could not be found.
+ CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const;
+
/// addedConstructor - Notify the class that another constructor has
/// been added. This routine helps maintain information about the
/// class based on which constructors have been added.
@@ -509,9 +597,23 @@ public:
return data().UserDeclaredCopyConstructor;
}
+ /// \brief Determine whether this class has had its copy constructor
+ /// declared, either via the user or via an implicit declaration.
+ ///
+ /// This value is used for lazy creation of copy constructors.
+ bool hasDeclaredCopyConstructor() const {
+ return data().DeclaredCopyConstructor;
+ }
+
+ /// \brief Note whether this class has already had its copy constructor
+ /// declared.
+ void setDeclaredCopyConstructor(bool DCC) {
+ data().DeclaredCopyConstructor = DCC;
+ }
+
/// addedAssignmentOperator - Notify the class that another assignment
/// operator has been added. This routine helps maintain information about the
- /// class based on which operators have been added.
+ /// class based on which operators have been added.
void addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl);
/// hasUserDeclaredCopyAssignment - Whether this class has a
@@ -521,6 +623,20 @@ public:
return data().UserDeclaredCopyAssignment;
}
+ /// \brief Determine whether this class has had its copy assignment operator
+ /// declared, either via the user or via an implicit declaration.
+ ///
+ /// This value is used for lazy creation of copy assignment operators.
+ bool hasDeclaredCopyAssignment() const {
+ return data().DeclaredCopyAssignment;
+ }
+
+ /// \brief Note whether this class has already had its copy assignment
+ /// operator declared.
+ void setDeclaredCopyAssignment(bool DCA) {
+ data().DeclaredCopyAssignment = DCA;
+ }
+
/// hasUserDeclaredDestructor - Whether this class has a
/// user-declared destructor. When false, a destructor will be
/// implicitly declared.
@@ -533,8 +649,21 @@ public:
/// fully defined, a destructor will be implicitly declared.
void setUserDeclaredDestructor(bool UCD) {
data().UserDeclaredDestructor = UCD;
+ if (UCD)
+ data().DeclaredDestructor = true;
}
+ /// \brief Determine whether this class has had its destructor declared,
+ /// either via the user or via an implicit declaration.
+ ///
+ /// This value is used for lazy creation of destructors.
+ bool hasDeclaredDestructor() const { return data().DeclaredDestructor; }
+
+ /// \brief Note whether this class has already had its destructor declared.
+ void setDeclaredDestructor(bool DD) {
+ data().DeclaredDestructor = DD;
+ }
+
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
UnresolvedSetImpl *getConversionFunctions() {
@@ -726,10 +855,10 @@ public:
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
/// getDefaultConstructor - Returns the default constructor for this class
- CXXConstructorDecl *getDefaultConstructor(ASTContext &Context);
+ CXXConstructorDecl *getDefaultConstructor();
/// getDestructor - Returns the destructor decl for this class.
- CXXDestructorDecl *getDestructor(ASTContext &Context) const;
+ CXXDestructorDecl *getDestructor() const;
/// isLocalClass - If the class is a local class [class.local], returns
/// the enclosing function declaration.
@@ -920,14 +1049,15 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
- return K == CXXRecord ||
- K == ClassTemplateSpecialization ||
- K == ClassTemplatePartialSpecialization;
+ return K >= firstCXXRecord && K <= lastCXXRecord;
}
static bool classof(const CXXRecordDecl *D) { return true; }
static bool classof(const ClassTemplateSpecializationDecl *D) {
return true;
}
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// CXXMethodDecl - Represents a static or instance method of a
@@ -984,6 +1114,7 @@ public:
method_iterator begin_overridden_methods() const;
method_iterator end_overridden_methods() const;
+ unsigned size_overridden_methods() const;
/// getParent - Returns the parent of this method declaration, which
/// is the class in which this method is defined.
@@ -1012,7 +1143,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXMethodDecl *D) { return true; }
static bool classofKind(Kind K) {
- return K >= CXXMethod && K <= CXXConversion;
+ return K >= firstCXXMethod && K <= lastCXXMethod;
}
};
@@ -1387,6 +1518,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConstructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConstructor; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// CXXDestructorDecl - Represents a C++ destructor within a
@@ -1450,6 +1584,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXDestructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXDestructor; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// CXXConversionDecl - Represents a C++ conversion function within a
@@ -1504,6 +1641,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConversionDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConversion; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// LinkageSpecDecl - This represents a linkage specification. For example:
@@ -1607,7 +1747,7 @@ class UsingDirectiveDecl : public NamedDecl {
SourceLocation IdentLoc,
NamedDecl *Nominated,
DeclContext *CommonAncestor)
- : NamedDecl(Decl::UsingDirective, DC, L, getName()),
+ : NamedDecl(UsingDirective, DC, L, getName()),
NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange),
Qualifier(Qualifier), IdentLoc(IdentLoc),
NominatedNamespace(Nominated),
@@ -1680,7 +1820,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDirectiveDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::UsingDirective; }
+ static bool classofKind(Kind K) { return K == UsingDirective; }
// Friend for getUsingDirectiveName.
friend class DeclContext;
@@ -1714,7 +1854,7 @@ class NamespaceAliasDecl : public NamedDecl {
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc, NamedDecl *Namespace)
- : NamedDecl(Decl::NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
+ : NamedDecl(NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
QualifierRange(QualifierRange), Qualifier(Qualifier),
IdentLoc(IdentLoc), Namespace(Namespace) { }
@@ -1786,7 +1926,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceAliasDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::NamespaceAlias; }
+ static bool classofKind(Kind K) { return K == NamespaceAlias; }
};
/// UsingShadowDecl - Represents a shadow declaration introduced into
@@ -1809,9 +1949,12 @@ class UsingShadowDecl : public NamedDecl {
UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
NamedDecl *Target)
- : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()),
+ : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
Underlying(Target), Using(Using) {
- IdentifierNamespace = Target->getIdentifierNamespace();
+ if (Target) {
+ setDeclName(Target->getDeclName());
+ IdentifierNamespace = Target->getIdentifierNamespace();
+ }
setImplicit();
}
@@ -1828,7 +1971,11 @@ public:
/// \brief Sets the underlying declaration which has been brought into the
/// local scope.
- void setTargetDecl(NamedDecl* ND) { Underlying = ND; }
+ void setTargetDecl(NamedDecl* ND) {
+ assert(ND && "Target decl is null!");
+ Underlying = ND;
+ IdentifierNamespace = ND->getIdentifierNamespace();
+ }
/// \brief Gets the using declaration to which this declaration is tied.
UsingDecl *getUsingDecl() const { return Using; }
@@ -1866,7 +2013,7 @@ class UsingDecl : public NamedDecl {
UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
SourceLocation UL, NestedNameSpecifier* TargetNNS,
DeclarationName Name, bool IsTypeNameArg)
- : NamedDecl(Decl::Using, DC, L, Name),
+ : NamedDecl(Using, DC, L, Name),
NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
IsTypeName(IsTypeNameArg) {
}
@@ -1934,7 +2081,10 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::Using; }
+ static bool classofKind(Kind K) { return K == Using; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// UnresolvedUsingValueDecl - Represents a dependent using
@@ -1960,7 +2110,7 @@ class UnresolvedUsingValueDecl : public ValueDecl {
NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc,
DeclarationName TargetName)
- : ValueDecl(Decl::UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
+ : ValueDecl(UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
TargetNestedNameSpecifier(TargetNNS)
{ }
@@ -1997,7 +2147,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingValue; }
+ static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
};
/// UnresolvedUsingTypenameDecl - Represents a dependent using
@@ -2026,7 +2176,7 @@ class UnresolvedUsingTypenameDecl : public TypeDecl {
SourceLocation TypenameLoc,
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
- : TypeDecl(Decl::UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
+ : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
{ }
@@ -2070,7 +2220,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingTypename; }
+ static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
};
/// StaticAssertDecl - Represents a C++0x static_assert declaration.
@@ -2098,7 +2248,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(StaticAssertDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::StaticAssert; }
+ static bool classofKind(Kind K) { return K == StaticAssert; }
};
/// Insertion operator for diagnostics. This allows sending AccessSpecifier's
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index a20625da56b7..2807d16379ae 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -59,10 +59,14 @@ private:
FriendLoc(FriendL) {
}
+ explicit FriendDecl(EmptyShell Empty)
+ : Decl(Decl::Friend, Empty), NextFriend(0) { }
+
public:
static FriendDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, FriendUnion Friend_,
SourceLocation FriendL);
+ static FriendDecl *Create(ASTContext &C, EmptyShell Empty);
/// If this friend declaration names an (untemplated but
/// possibly dependent) type, return the type; otherwise
@@ -87,6 +91,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FriendDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::Friend; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// An iterator over the friend declarations of a class.
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 97d165696aad..fb8596f50a0b 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -239,6 +239,12 @@ public:
QualType getResultType() const { return MethodDeclType; }
void setResultType(QualType T) { MethodDeclType = T; }
+ /// \brief Determine the type of an expression that sends a message to this
+ /// function.
+ QualType getSendResultType() const {
+ return getResultType().getCallResultType(getASTContext());
+ }
+
TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
@@ -417,8 +423,8 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCContainerDecl *D) { return true; }
static bool classofKind(Kind K) {
- return K >= ObjCContainerFirst &&
- K <= ObjCContainerLast;
+ return K >= firstObjCContainer &&
+ K <= lastObjCContainer;
}
static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
@@ -550,8 +556,8 @@ public:
void setCategoryList(ObjCCategoryDecl *category) {
CategoryList = category;
}
-
- ObjCCategoryDecl* getClassExtension() const;
+
+ ObjCCategoryDecl* getFirstClassExtension() const;
ObjCPropertyDecl
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
@@ -983,6 +989,7 @@ public:
}
bool IsClassExtension() const { return getIdentifier() == 0; }
+ const ObjCCategoryDecl *getNextClassExtension() const;
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
ivar_iterator ivar_begin() const {
@@ -1059,7 +1066,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCImplDecl *D) { return true; }
static bool classofKind(Kind K) {
- return K >= ObjCImplFirst && K <= ObjCImplLast;
+ return K >= firstObjCImpl && K <= lastObjCImpl;
}
};
@@ -1306,9 +1313,9 @@ public:
enum PropertyControl { None, Required, Optional };
private:
SourceLocation AtLoc; // location of @property
- QualType DeclType;
+ TypeSourceInfo *DeclType;
unsigned PropertyAttributes : 8;
-
+ unsigned PropertyAttributesAsWritten : 8;
// @required/@optional
unsigned PropertyImplementation : 2;
@@ -1320,9 +1327,11 @@ private:
ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- SourceLocation AtLocation, QualType T)
+ SourceLocation AtLocation, TypeSourceInfo *T)
: NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), DeclType(T),
- PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
+ PropertyAttributes(OBJC_PR_noattr),
+ PropertyAttributesAsWritten(OBJC_PR_noattr),
+ PropertyImplementation(None),
GetterName(Selector()),
SetterName(Selector()),
GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
@@ -1330,13 +1339,14 @@ public:
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
IdentifierInfo *Id, SourceLocation AtLocation,
- QualType T,
+ TypeSourceInfo *T,
PropertyControl propControl = None);
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation L) { AtLoc = L; }
- QualType getType() const { return DeclType; }
- void setType(QualType T) { DeclType = T; }
+ TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
+ QualType getType() const { return DeclType->getType(); }
+ void setType(TypeSourceInfo *T) { DeclType = T; }
PropertyAttributeKind getPropertyAttributes() const {
return PropertyAttributeKind(PropertyAttributes);
@@ -1345,6 +1355,14 @@ public:
PropertyAttributes |= PRVal;
}
+ PropertyAttributeKind getPropertyAttributesAsWritten() const {
+ return PropertyAttributeKind(PropertyAttributesAsWritten);
+ }
+
+ void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
+ PropertyAttributesAsWritten = PRVal;
+ }
+
void makeitReadWriteAttribute(void) {
PropertyAttributes &= ~OBJC_PR_readonly;
PropertyAttributes |= OBJC_PR_readwrite;
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index b7b90b14adfd..135dd3ae78d3 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -180,18 +180,29 @@ public:
TemplateArgumentListBuilder &Builder,
bool TakeArgs);
+ /// TemplateArgumentList - It copies the template arguments into a locally
+ /// new[]'d array.
+ TemplateArgumentList(ASTContext &Context,
+ const TemplateArgument *Args, unsigned NumArgs);
+
/// Produces a shallow copy of the given template argument list. This
/// assumes that the input argument list outlives it. This takes the list as
/// a pointer to avoid looking like a copy constructor, since this really
/// really isn't safe to use that way.
explicit TemplateArgumentList(const TemplateArgumentList *Other);
-
+
+ TemplateArgumentList() : NumFlatArguments(0), NumStructuredArguments(0) { }
+
/// Used to release the memory associated with a TemplateArgumentList
/// object. FIXME: This is currently not called anywhere, but the
/// memory will still be freed when using a BumpPtrAllocator.
void Destroy(ASTContext &C);
~TemplateArgumentList();
+
+ /// \brief Copies the template arguments into a locally new[]'d array.
+ void init(ASTContext &Context,
+ const TemplateArgument *Args, unsigned NumArgs);
/// \brief Retrieve the template argument at a given index.
const TemplateArgument &get(unsigned Idx) const {
@@ -261,12 +272,27 @@ public:
static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
static bool classofKind(Kind K) {
- return K >= TemplateFirst && K <= TemplateLast;
+ return K >= firstTemplate && K <= lastTemplate;
+ }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(TemplateParams->getTemplateLoc(),
+ TemplatedDecl->getSourceRange().getEnd());
}
protected:
NamedDecl *TemplatedDecl;
TemplateParameterList* TemplateParams;
+
+public:
+ /// \brief Initialize the underlying templated declaration and
+ /// template parameters.
+ void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
+ assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
+ assert(TemplateParams == 0 && "TemplateParams already set!");
+ TemplatedDecl = templatedDecl;
+ TemplateParams = templateParams;
+ }
};
/// \brief Provides information about a function template specialization,
@@ -353,8 +379,9 @@ class MemberSpecializationInfo {
public:
explicit
- MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK)
- : MemberAndTSK(IF, TSK - 1), PointOfInstantiation() {
+ MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
+ SourceLocation POI = SourceLocation())
+ : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
assert(TSK != TSK_Undeclared &&
"Cannot encode undeclared template specializations for members");
}
@@ -602,6 +629,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classofKind(Kind K) { return K == FunctionTemplate; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
//===----------------------------------------------------------------------===//
@@ -634,9 +664,11 @@ protected:
public:
/// Get the nesting depth of the template parameter.
unsigned getDepth() const { return Depth; }
+ void setDepth(unsigned D) { Depth = D; }
/// Get the position of the template parameter within its parameter list.
unsigned getPosition() const { return Position; }
+ void setPosition(unsigned P) { Position = P; }
/// Get the index of the template parameter within its parameter list.
unsigned getIndex() const { return Position; }
@@ -675,6 +707,7 @@ public:
SourceLocation L, unsigned D, unsigned P,
IdentifierInfo *Id, bool Typename,
bool ParameterPack);
+ static TemplateTypeParmDecl *Create(ASTContext &C, EmptyShell Empty);
/// \brief Whether this template type parameter was declared with
/// the 'typename' keyword. If not, it was declared with the 'class'
@@ -711,6 +744,13 @@ public:
DefaultArgument = 0;
InheritedDefault = false;
}
+
+ /// \brief Set whether this template type parameter was declared with
+ /// the 'typename' or 'class' keyword.
+ void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
+
+ /// \brief Set whether this is a parameter pack.
+ void setParameterPack(bool isParamPack) { ParameterPack = isParamPack; }
/// \brief Retrieve the depth of the template parameter.
unsigned getDepth() const;
@@ -734,15 +774,16 @@ public:
/// @endcode
class NonTypeTemplateParmDecl
: public VarDecl, protected TemplateParmPosition {
- /// \brief The default template argument, if any.
- Expr *DefaultArgument;
+ /// \brief The default template argument, if any, and whether or not
+ /// it was inherited.
+ llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo)
: VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None,
VarDecl::None),
- TemplateParmPosition(D, P), DefaultArgument(0)
+ TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false)
{ }
public:
@@ -751,22 +792,43 @@ public:
unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
using TemplateParmPosition::getDepth;
+ using TemplateParmPosition::setDepth;
using TemplateParmPosition::getPosition;
+ using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const { return DefaultArgument; }
+ bool hasDefaultArgument() const {
+ return DefaultArgumentAndInherited.getPointer() != 0;
+ }
/// \brief Retrieve the default argument, if any.
- Expr *getDefaultArgument() const { return DefaultArgument; }
+ Expr *getDefaultArgument() const {
+ return DefaultArgumentAndInherited.getPointer();
+ }
/// \brief Retrieve the location of the default argument, if any.
SourceLocation getDefaultArgumentLoc() const;
- /// \brief Set the default argument for this template parameter.
- void setDefaultArgument(Expr *DefArg) {
- DefaultArgument = DefArg;
+ /// \brief Determines whether the default argument was inherited
+ /// from a previous declaration of this template.
+ bool defaultArgumentWasInherited() const {
+ return DefaultArgumentAndInherited.getInt();
+ }
+
+ /// \brief Set the default argument for this template parameter, and
+ /// whether that default argument was inherited from another
+ /// declaration.
+ void setDefaultArgument(Expr *DefArg, bool Inherited) {
+ DefaultArgumentAndInherited.setPointer(DefArg);
+ DefaultArgumentAndInherited.setInt(Inherited);
+ }
+
+ /// \brief Removes the default argument of this template parameter.
+ void removeDefaultArgument() {
+ DefaultArgumentAndInherited.setPointer(0);
+ DefaultArgumentAndInherited.setInt(false);
}
// Implement isa/cast/dyncast/etc.
@@ -785,14 +847,17 @@ public:
class TemplateTemplateParmDecl
: public TemplateDecl, protected TemplateParmPosition {
- /// \brief The default template argument, if any.
+ /// DefaultArgument - The default template argument, if any.
TemplateArgumentLoc DefaultArgument;
+ /// Whether or not the default argument was inherited.
+ bool DefaultArgumentWasInherited;
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
unsigned D, unsigned P,
IdentifierInfo *Id, TemplateParameterList *Params)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
- TemplateParmPosition(D, P), DefaultArgument()
+ TemplateParmPosition(D, P), DefaultArgument(),
+ DefaultArgumentWasInherited(false)
{ }
public:
@@ -807,24 +872,45 @@ public:
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const {
- return !DefaultArgument.getArgument().isNull();
+ bool hasDefaultArgument() const {
+ return !DefaultArgument.getArgument().isNull();
}
/// \brief Retrieve the default argument, if any.
- const TemplateArgumentLoc &getDefaultArgument() const {
- return DefaultArgument;
+ const TemplateArgumentLoc &getDefaultArgument() const {
+ return DefaultArgument;
+ }
+
+ /// \brief Retrieve the location of the default argument, if any.
+ SourceLocation getDefaultArgumentLoc() const;
+
+ /// \brief Determines whether the default argument was inherited
+ /// from a previous declaration of this template.
+ bool defaultArgumentWasInherited() const {
+ return DefaultArgumentWasInherited;
}
- /// \brief Set the default argument for this template parameter.
- void setDefaultArgument(const TemplateArgumentLoc &DefArg) {
+ /// \brief Set the default argument for this template parameter, and
+ /// whether that default argument was inherited from another
+ /// declaration.
+ void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
DefaultArgument = DefArg;
+ DefaultArgumentWasInherited = Inherited;
+ }
+
+ /// \brief Removes the default argument of this template parameter.
+ void removeDefaultArgument() {
+ DefaultArgument = TemplateArgumentLoc();
+ DefaultArgumentWasInherited = false;
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// \brief Represents a class template specialization, which refers to
@@ -860,9 +946,22 @@ class ClassTemplateSpecializationDecl
llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
SpecializedTemplate;
- /// \brief The type-as-written of an explicit template specialization.
+ /// \brief Further info for explicit template specialization/instantiation.
+ struct ExplicitSpecializationInfo {
+ /// \brief The type-as-written.
+ TypeSourceInfo *TypeAsWritten;
+ /// \brief The location of the extern keyword.
+ SourceLocation ExternLoc;
+ /// \brief The location of the template keyword.
+ SourceLocation TemplateKeywordLoc;
+
+ ExplicitSpecializationInfo()
+ : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+ };
+
+ /// \brief Further info for explicit template specialization/instantiation.
/// Does not apply to implicit specializations.
- TypeSourceInfo *TypeAsWritten;
+ ExplicitSpecializationInfo *ExplicitInfo;
/// \brief The template arguments used to describe this specialization.
TemplateArgumentList TemplateArgs;
@@ -881,12 +980,16 @@ protected:
TemplateArgumentListBuilder &Builder,
ClassTemplateSpecializationDecl *PrevDecl);
+ explicit ClassTemplateSpecializationDecl(Kind DK);
+
public:
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
ClassTemplateSpecializationDecl *PrevDecl);
+ static ClassTemplateSpecializationDecl *
+ Create(ASTContext &Context, EmptyShell Empty);
virtual void Destroy(ASTContext& C);
@@ -903,6 +1006,14 @@ public:
return TemplateArgs;
}
+ /// \brief Initialize the template arguments of the class template
+ /// specialization.
+ void initTemplateArgs(TemplateArgument *Args, unsigned NumArgs) {
+ assert(TemplateArgs.flat_size() == 0 &&
+ "Template arguments already initialized!");
+ TemplateArgs.init(getASTContext(), Args, NumArgs);
+ }
+
/// \brief Determine the kind of specialization that this
/// declaration represents.
TemplateSpecializationKind getSpecializationKind() const {
@@ -943,6 +1054,19 @@ public:
SpecializedTemplate.get<ClassTemplateDecl*>());
}
+ /// \brief Retrieve the class template or class template partial
+ /// specialization which was specialized by this.
+ llvm::PointerUnion<ClassTemplateDecl *,
+ ClassTemplatePartialSpecializationDecl *>
+ getSpecializedTemplateOrPartial() const {
+ if (SpecializedPartialSpecialization *PartialSpec
+ = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+ return PartialSpec->PartialSpecialization;
+
+ return const_cast<ClassTemplateDecl*>(
+ SpecializedTemplate.get<ClassTemplateDecl*>());
+ }
+
/// \brief Retrieve the set of template arguments that should be used
/// to instantiate members of the class template or class template partial
/// specialization from which this class template specialization was
@@ -967,6 +1091,8 @@ public:
/// template arguments have been deduced.
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
TemplateArgumentList *TemplateArgs) {
+ assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
+ "Already set to a class template partial specialization!");
SpecializedPartialSpecialization *PS
= new (getASTContext()) SpecializedPartialSpecialization();
PS->PartialSpecialization = PartialSpec;
@@ -974,17 +1100,59 @@ public:
SpecializedTemplate = PS;
}
+ /// \brief Note that this class template specialization is actually an
+ /// instantiation of the given class template partial specialization whose
+ /// template arguments have been deduced.
+ void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
+ TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs) {
+ ASTContext &Ctx = getASTContext();
+ setInstantiationOf(PartialSpec,
+ new (Ctx) TemplateArgumentList(Ctx, TemplateArgs,
+ NumTemplateArgs));
+ }
+
+ /// \brief Note that this class template specialization is an instantiation
+ /// of the given class template.
+ void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
+ assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
+ "Previously set to a class template partial specialization!");
+ SpecializedTemplate = TemplDecl;
+ }
+
/// \brief Sets the type of this specialization as it was written by
/// the user. This will be a class template specialization type.
void setTypeAsWritten(TypeSourceInfo *T) {
- TypeAsWritten = T;
+ if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
+ ExplicitInfo->TypeAsWritten = T;
}
-
/// \brief Gets the type of this specialization as it was written by
/// the user, if it was so written.
TypeSourceInfo *getTypeAsWritten() const {
- return TypeAsWritten;
+ return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
+ }
+
+ /// \brief Gets the location of the extern keyword, if present.
+ SourceLocation getExternLoc() const {
+ return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
+ }
+ /// \brief Sets the location of the extern keyword.
+ void setExternLoc(SourceLocation Loc) {
+ if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
+ ExplicitInfo->ExternLoc = Loc;
+ }
+
+ /// \brief Sets the location of the template keyword.
+ void setTemplateKeywordLoc(SourceLocation Loc) {
+ if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
+ ExplicitInfo->TemplateKeywordLoc = Loc;
}
+ /// \brief Gets the location of the template keyword, if present.
+ SourceLocation getTemplateKeywordLoc() const {
+ return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
+ }
+
+ SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); }
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
@@ -1001,8 +1169,8 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
- return K == ClassTemplateSpecialization ||
- K == ClassTemplatePartialSpecialization;
+ return K >= firstClassTemplateSpecialization &&
+ K <= lastClassTemplateSpecialization;
}
static bool classof(const ClassTemplateSpecializationDecl *) {
@@ -1053,6 +1221,12 @@ class ClassTemplatePartialSpecializationDecl
TemplateParams(Params), ArgsAsWritten(ArgInfos),
NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
InstantiatedFromMember(0, false) { }
+
+ ClassTemplatePartialSpecializationDecl()
+ : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
+ TemplateParams(0), ArgsAsWritten(0),
+ NumArgsAsWritten(0), SequenceNumber(0),
+ InstantiatedFromMember(0, false) { }
public:
static ClassTemplatePartialSpecializationDecl *
@@ -1065,16 +1239,26 @@ public:
ClassTemplatePartialSpecializationDecl *PrevDecl,
unsigned SequenceNumber);
+ static ClassTemplatePartialSpecializationDecl *
+ Create(ASTContext &Context, EmptyShell Empty);
+
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
return TemplateParams;
}
+ void initTemplateParameters(TemplateParameterList *Params) {
+ assert(TemplateParams == 0 && "TemplateParams already set");
+ TemplateParams = Params;
+ }
+
/// Get the template arguments as written.
TemplateArgumentLoc *getTemplateArgsAsWritten() const {
return ArgsAsWritten;
}
+ void initTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgInfos);
+
/// Get the number of template arguments as written.
unsigned getNumTemplateArgsAsWritten() const {
return NumArgsAsWritten;
@@ -1083,6 +1267,7 @@ public:
/// \brief Get the sequence number for this class template partial
/// specialization.
unsigned getSequenceNumber() const { return SequenceNumber; }
+ void setSequenceNumber(unsigned N) { SequenceNumber = N; }
/// \brief Retrieve the member class template partial specialization from
/// which this particular class template partial specialization was
@@ -1199,26 +1384,19 @@ protected:
llvm::PointerIntPair<ClassTemplateDecl *, 1, bool> InstantiatedFromMember;
};
- // FIXME: Combine PreviousDeclaration with CommonPtr, as in
- // FunctionTemplateDecl.
-
- /// \brief Previous declaration of this class template.
- ClassTemplateDecl *PreviousDeclaration;
+ /// \brief A pointer to the previous declaration (if this is a redeclaration)
+ /// or to the data that is common to all declarations of this class template.
+ llvm::PointerUnion<Common*, ClassTemplateDecl*> CommonOrPrev;
- /// \brief Pointer to the data that is common to all of the
- /// declarations of this class template.
- ///
- /// The first declaration of a class template (e.g., the declaration
- /// with no "previous declaration") owns this pointer.
- Common *CommonPtr;
+ /// \brief Retrieves the "common" pointer shared by all
+ /// (re-)declarations of the same class template. Calling this routine
+ /// may implicitly allocate memory for the common pointer.
+ Common *getCommonPtr();
ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl,
- ClassTemplateDecl *PrevDecl, Common *CommonPtr)
+ TemplateParameterList *Params, NamedDecl *Decl)
: TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
- PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { }
-
- ~ClassTemplateDecl();
+ CommonOrPrev((Common*)0) { }
public:
/// Get the underlying class declarations of the template.
@@ -1226,13 +1404,30 @@ public:
return static_cast<CXXRecordDecl *>(TemplatedDecl);
}
- /// \brief Retrieve the previous declaration of this template.
- ClassTemplateDecl *getPreviousDeclaration() const {
- return PreviousDeclaration;
+ /// \brief Retrieve the previous declaration of this class template, or
+ /// NULL if no such declaration exists.
+ const ClassTemplateDecl *getPreviousDeclaration() const {
+ return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ ClassTemplateDecl *getPreviousDeclaration() {
+ return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
+ }
+
+ /// \brief Set the previous declaration of this class template.
+ void setPreviousDeclaration(ClassTemplateDecl *Prev) {
+ if (Prev)
+ CommonOrPrev = Prev;
}
virtual ClassTemplateDecl *getCanonicalDecl();
+ const ClassTemplateDecl *getCanonicalDecl() const {
+ return const_cast<ClassTemplateDecl*>(this)->getCanonicalDecl();
+ }
+
/// Create a class template node.
static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -1243,14 +1438,14 @@ public:
/// \brief Retrieve the set of specializations of this class template.
llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
- return CommonPtr->Specializations;
+ return getCommonPtr()->Specializations;
}
/// \brief Retrieve the set of partial specializations of this class
/// template.
llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations() {
- return CommonPtr->PartialSpecializations;
+ return getCommonPtr()->PartialSpecializations;
}
/// \brief Retrieve the partial specializations as an ordered list.
@@ -1281,7 +1476,7 @@ public:
/// typedef array this_type; // "array" is equivalent to "array<T, N>"
/// };
/// \endcode
- QualType getInjectedClassNameSpecialization(ASTContext &Context);
+ QualType getInjectedClassNameSpecialization();
/// \brief Retrieve the member class template that this class template was
/// derived from.
@@ -1303,13 +1498,13 @@ public:
/// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
///
/// \returns null if this is not an instantiation of a member class template.
- ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return CommonPtr->InstantiatedFromMember.getPointer();
+ ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return getCommonPtr()->InstantiatedFromMember.getPointer();
}
void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
- assert(!CommonPtr->InstantiatedFromMember.getPointer());
- CommonPtr->InstantiatedFromMember.setPointer(CTD);
+ assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
+ getCommonPtr()->InstantiatedFromMember.setPointer(CTD);
}
/// \brief Determines whether this template was a specialization of a
@@ -1328,14 +1523,14 @@ public:
/// struct X<int>::Inner { /* ... */ };
/// \endcode
bool isMemberSpecialization() {
- return CommonPtr->InstantiatedFromMember.getInt();
+ return getCommonPtr()->InstantiatedFromMember.getInt();
}
/// \brief Note that this member template is a specialization.
void setMemberSpecialization() {
- assert(CommonPtr->InstantiatedFromMember.getPointer() &&
+ assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
"Only member templates can be member template specializations");
- CommonPtr->InstantiatedFromMember.setInt(true);
+ getCommonPtr()->InstantiatedFromMember.setInt(true);
}
// Implement isa/cast/dyncast support
@@ -1344,6 +1539,9 @@ public:
static bool classofKind(Kind K) { return K == ClassTemplate; }
virtual void Destroy(ASTContext& C);
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// Declaration of a friend template. For example:
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
index 140e5c0a2a99..aee1998028eb 100644
--- a/include/clang/AST/DeclVisitor.h
+++ b/include/clang/AST/DeclVisitor.h
@@ -30,20 +30,19 @@ class DeclVisitor {
public:
RetTy Visit(Decl *D) {
switch (D->getKind()) {
- default: assert(false && "Decl that isn't part of DeclNodes.def!");
-#define DECL(Derived, Base) \
- case Decl::Derived: DISPATCH(Derived##Decl, Derived##Decl);
-#define ABSTRACT_DECL(Derived, Base)
-#include "clang/AST/DeclNodes.def"
+ default: assert(false && "Decl that isn't part of DeclNodes.inc!");
+#define DECL(DERIVED, BASE) \
+ case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl);
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
}
}
// If the implementation chooses not to implement a certain visit
// method, fall back to the parent.
-#define DECL(Derived, Base) \
- RetTy Visit##Derived##Decl(Derived##Decl *D) { DISPATCH(Base, Base); }
-#define ABSTRACT_DECL(Derived, Base) DECL(Derived, Base)
-#include "clang/AST/DeclNodes.def"
+#define DECL(DERIVED, BASE) \
+ RetTy Visit##DERIVED##Decl(DERIVED##Decl *D) { DISPATCH(BASE, BASE); }
+#include "clang/AST/DeclNodes.inc"
RetTy VisitDecl(Decl *D) { return RetTy(); }
};
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 66639e2ef733..807644349e56 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -162,9 +162,6 @@ public:
};
isLvalueResult isLvalue(ASTContext &Ctx) const;
- // Same as above, but excluding checks for non-object and void types in C
- isLvalueResult isLvalueInternal(ASTContext &Ctx) const;
-
/// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
/// does not have an incomplete type, does not have a const-qualified type,
/// and if it is a structure or union, does not have any member (including,
@@ -194,6 +191,95 @@ public:
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
SourceLocation *Loc = 0) const;
+ /// \brief The return type of classify(). Represents the C++0x expression
+ /// taxonomy.
+ class Classification {
+ public:
+ /// \brief The various classification results. Most of these mean prvalue.
+ enum Kinds {
+ CL_LValue,
+ CL_XValue,
+ CL_Function, // Functions cannot be lvalues in C.
+ CL_Void, // Void cannot be an lvalue in C.
+ CL_DuplicateVectorComponents, // A vector shuffle with dupes.
+ CL_MemberFunction, // An expression referring to a member function
+ CL_SubObjCPropertySetting,
+ CL_ClassTemporary, // A prvalue of class type
+ CL_PRValue // A prvalue for any other reason, of any other type
+ };
+ /// \brief The results of modification testing.
+ enum ModifiableType {
+ CM_Untested, // testModifiable was false.
+ CM_Modifiable,
+ CM_RValue, // Not modifiable because it's an rvalue
+ CM_Function, // Not modifiable because it's a function; C++ only
+ CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
+ CM_NotBlockQualified, // Not captured in the closure
+ CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
+ CM_ConstQualified,
+ CM_ArrayType,
+ CM_IncompleteType
+ };
+
+ private:
+ friend class Expr;
+
+ unsigned short Kind;
+ unsigned short Modifiable;
+
+ explicit Classification(Kinds k, ModifiableType m)
+ : Kind(k), Modifiable(m)
+ {}
+
+ public:
+ Classification() {}
+
+ Kinds getKind() const { return static_cast<Kinds>(Kind); }
+ ModifiableType getModifiable() const {
+ assert(Modifiable != CM_Untested && "Did not test for modifiability.");
+ return static_cast<ModifiableType>(Modifiable);
+ }
+ bool isLValue() const { return Kind == CL_LValue; }
+ bool isXValue() const { return Kind == CL_XValue; }
+ bool isGLValue() const { return Kind <= CL_XValue; }
+ bool isPRValue() const { return Kind >= CL_Function; }
+ bool isRValue() const { return Kind >= CL_XValue; }
+ bool isModifiable() const { return getModifiable() == CM_Modifiable; }
+ };
+ /// \brief classify - Classify this expression according to the C++0x
+ /// expression taxonomy.
+ ///
+ /// C++0x defines ([basic.lval]) a new taxonomy of expressions to replace the
+ /// old lvalue vs rvalue. This function determines the type of expression this
+ /// is. There are three expression types:
+ /// - lvalues are classical lvalues as in C++03.
+ /// - prvalues are equivalent to rvalues in C++03.
+ /// - xvalues are expressions yielding unnamed rvalue references, e.g. a
+ /// function returning an rvalue reference.
+ /// lvalues and xvalues are collectively referred to as glvalues, while
+ /// prvalues and xvalues together form rvalues.
+ /// If a
+ Classification Classify(ASTContext &Ctx) const {
+ return ClassifyImpl(Ctx, 0);
+ }
+
+ /// \brief classifyModifiable - Classify this expression according to the
+ /// C++0x expression taxonomy, and see if it is valid on the left side
+ /// of an assignment.
+ ///
+ /// This function extends classify in that it also tests whether the
+ /// expression is modifiable (C99 6.3.2.1p1).
+ /// \param Loc A source location that might be filled with a relevant location
+ /// if the expression is not modifiable.
+ Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const{
+ return ClassifyImpl(Ctx, &Loc);
+ }
+
+private:
+ Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const;
+
+public:
+
/// \brief If this expression refers to a bit-field, retrieve the
/// declaration of that bit-field.
FieldDecl *getBitField();
@@ -414,6 +500,7 @@ struct ExplicitTemplateArgumentList {
void initializeFrom(const TemplateArgumentListInfo &List);
void copyInto(TemplateArgumentListInfo &List) const;
+ static std::size_t sizeFor(unsigned NumTemplateArgs);
static std::size_t sizeFor(const TemplateArgumentListInfo &List);
};
@@ -474,27 +561,21 @@ class DeclRefExpr : public Expr {
ValueDecl *D, SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T);
+
+ /// \brief Construct an empty declaration reference expression.
+ explicit DeclRefExpr(EmptyShell Empty)
+ : Expr(DeclRefExprClass, Empty) { }
-protected:
/// \brief Computes the type- and value-dependence flags for this
/// declaration reference expression.
void computeDependence();
- DeclRefExpr(StmtClass SC, ValueDecl *d, QualType t, SourceLocation l) :
- Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) {
- computeDependence();
- }
-
public:
DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) :
Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) {
computeDependence();
}
- /// \brief Construct an empty declaration reference expression.
- explicit DeclRefExpr(EmptyShell Empty)
- : Expr(DeclRefExprClass, Empty) { }
-
static DeclRefExpr *Create(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -502,6 +583,10 @@ public:
SourceLocation NameLoc,
QualType T,
const TemplateArgumentListInfo *TemplateArgs = 0);
+
+ /// \brief Construct an empty declaration reference expression.
+ static DeclRefExpr *CreateEmpty(ASTContext &Context,
+ bool HasQualifier, unsigned NumTemplateArgs);
ValueDecl *getDecl() { return DecoratedD.getPointer(); }
const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
@@ -591,6 +676,9 @@ public:
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class PCHStmtReader;
+ friend class PCHStmtWriter;
};
/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
@@ -1560,11 +1648,6 @@ public:
Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {}
- /// \brief Build an empty member reference expression.
- explicit MemberExpr(EmptyShell Empty)
- : Expr(MemberExprClass, Empty), HasQualifierOrFoundDecl(false),
- HasExplicitTemplateArgumentList(false) { }
-
static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifier *qual, SourceRange qualrange,
ValueDecl *memberdecl, DeclAccessPair founddecl,
@@ -1937,6 +2020,7 @@ public:
}
const CXXBaseSpecifierArray& getBasePath() const { return BasePath; }
+ CXXBaseSpecifierArray& getBasePath() { return BasePath; }
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstCastExprConstant &&
@@ -2169,7 +2253,8 @@ public:
/// predicates to categorize the respective opcodes.
bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; }
- bool isAdditiveOp() const { return Opc == Add || Opc == Sub; }
+ static bool isAdditiveOp(Opcode Opc) { return Opc == Add || Opc == Sub; }
+ bool isAdditiveOp() const { return isAdditiveOp(Opc); }
static bool isShiftOp(Opcode Opc) { return Opc == Shl || Opc == Shr; }
bool isShiftOp() const { return isShiftOp(Opc); }
@@ -3153,7 +3238,7 @@ public:
~ParenListExpr() {}
/// \brief Build an empty paren list.
- //explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
+ explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
unsigned getNumExprs() const { return NumExprs; }
@@ -3183,6 +3268,9 @@ public:
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class PCHStmtReader;
+ friend class PCHStmtWriter;
};
@@ -3305,12 +3393,15 @@ class BlockDeclRefExpr : public Expr {
SourceLocation Loc;
bool IsByRef : 1;
bool ConstQualAdded : 1;
+ Stmt *CopyConstructorVal;
public:
// FIXME: Fix type/value dependence!
BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef,
- bool constAdded = false)
- : Expr(BlockDeclRefExprClass, t, false, false), D(d), Loc(l), IsByRef(ByRef),
- ConstQualAdded(constAdded) {}
+ bool constAdded = false,
+ Stmt *copyConstructorVal = 0)
+ : Expr(BlockDeclRefExprClass, t, (!t.isNull() && t->isDependentType()),false),
+ D(d), Loc(l), IsByRef(ByRef),
+ ConstQualAdded(constAdded), CopyConstructorVal(copyConstructorVal) {}
// \brief Build an empty reference to a declared variable in a
// block.
@@ -3331,6 +3422,12 @@ public:
bool isConstQualAdded() const { return ConstQualAdded; }
void setConstQualAdded(bool C) { ConstQualAdded = C; }
+
+ const Expr *getCopyConstructorExpr() const
+ { return cast_or_null<Expr>(CopyConstructorVal); }
+ Expr *getCopyConstructorExpr()
+ { return cast_or_null<Expr>(CopyConstructorVal); }
+ void setCopyConstructorExpr(Expr *E) { CopyConstructorVal = E; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == BlockDeclRefExprClass;
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 0c493f36df09..b9553815d8eb 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -465,7 +465,6 @@ class CXXDefaultArgExpr : public Expr {
/// \brief The location where the default argument expression was used.
SourceLocation Loc;
-protected:
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
: Expr(SC,
param->hasUnparsedDefaultArg()
@@ -504,9 +503,6 @@ public:
// Retrieve the parameter that the argument was created from.
const ParmVarDecl *getParam() const { return Param.getPointer(); }
ParmVarDecl *getParam() { return Param.getPointer(); }
-
- /// isExprStored - Return true if this expression owns the expression.
- bool isExprStored() const { return Param.getInt(); }
// Retrieve the actual argument to the function call.
const Expr *getExpr() const {
@@ -519,16 +515,10 @@ public:
return *reinterpret_cast<Expr **> (this + 1);
return getParam()->getDefaultArg();
}
-
- void setExpr(Expr *E) {
- Param.setInt(true);
- Param.setPointer((ParmVarDecl*)E);
- }
/// \brief Retrieve the location where this default argument was actually
/// used.
SourceLocation getUsedLocation() const { return Loc; }
- void setUsedLocation(SourceLocation L) { Loc = L; }
virtual SourceRange getSourceRange() const {
// Default argument expressions have no representation in the
@@ -544,6 +534,9 @@ public:
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class PCHStmtReader;
+ friend class PCHStmtWriter;
};
/// CXXTemporary - Represents a C++ temporary.
@@ -655,6 +648,9 @@ public:
static CXXBindReferenceExpr *Create(ASTContext &C, Expr *SubExpr,
bool ExtendsLifetime,
bool RequiresTemporaryCopy);
+
+ explicit CXXBindReferenceExpr(EmptyShell Empty)
+ : Expr(CXXBindReferenceExprClass, Empty) { }
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
@@ -670,7 +666,7 @@ public:
// extendsLifetime - Whether binding this reference extends the lifetime of
// the expression being bound. FIXME: Add C++ reference.
- bool extendsLifetime() { return ExtendsLifetime; }
+ bool extendsLifetime() const { return ExtendsLifetime; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Stmt *T) {
@@ -681,6 +677,8 @@ public:
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class PCHStmtReader;
};
/// CXXConstructExpr - Represents a call to a C++ constructor.
@@ -711,13 +709,20 @@ protected:
ConstructionKind ConstructKind = CK_Complete);
~CXXConstructExpr() { }
+ /// \brief Construct an empty C++ construction expression.
+ CXXConstructExpr(StmtClass SC, EmptyShell Empty)
+ : Expr(SC, Empty), Constructor(0), Elidable(0), ZeroInitialization(0),
+ ConstructKind(0), Args(0), NumArgs(0) { }
+
virtual void DoDestroy(ASTContext &C);
public:
- /// \brief Construct an empty C++ construction expression that will store
- /// \p numargs arguments.
- CXXConstructExpr(EmptyShell Empty, ASTContext &C, unsigned numargs);
-
+ /// \brief Construct an empty C++ construction expression.
+ explicit CXXConstructExpr(EmptyShell Empty)
+ : Expr(CXXConstructExprClass, Empty), Constructor(0),
+ Elidable(0), ZeroInitialization(0),
+ ConstructKind(0), Args(0), NumArgs(0) { }
+
static CXXConstructExpr *Create(ASTContext &C, QualType T,
SourceLocation Loc,
CXXConstructorDecl *D, bool Elidable,
@@ -790,6 +795,8 @@ public:
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class PCHStmtReader;
};
/// CXXFunctionalCastExpr - Represents an explicit C++ type conversion
@@ -829,12 +836,8 @@ public:
///
/// This expression type represents a C++ "functional" cast
/// (C++[expr.type.conv]) with N != 1 arguments that invokes a
-/// constructor to build a temporary object. If N == 0 but no
-/// constructor will be called (because the functional cast is
-/// performing a value-initialized an object whose class type has no
-/// user-declared constructors), CXXZeroInitValueExpr will represent
-/// the functional cast. Finally, with N == 1 arguments the functional
-/// cast expression will be represented by CXXFunctionalCastExpr.
+/// constructor to build a temporary object. With N == 1 arguments the
+/// functional cast expression will be represented by CXXFunctionalCastExpr.
/// Example:
/// @code
/// struct X { X(int, float); }
@@ -853,6 +856,8 @@ public:
Expr **Args,unsigned NumArgs,
SourceLocation rParenLoc,
bool ZeroInitialization = false);
+ explicit CXXTemporaryObjectExpr(EmptyShell Empty)
+ : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) { }
~CXXTemporaryObjectExpr() { }
@@ -866,24 +871,25 @@ public:
return T->getStmtClass() == CXXTemporaryObjectExprClass;
}
static bool classof(const CXXTemporaryObjectExpr *) { return true; }
+
+ friend class PCHStmtReader;
};
-/// CXXZeroInitValueExpr - [C++ 5.2.3p2]
+/// CXXScalarValueInitExpr - [C++ 5.2.3p2]
/// Expression "T()" which creates a value-initialized rvalue of type
-/// T, which is either a non-class type or a class type without any
-/// user-defined constructors.
+/// T, which is a non-class type.
///
-class CXXZeroInitValueExpr : public Expr {
+class CXXScalarValueInitExpr : public Expr {
SourceLocation TyBeginLoc;
SourceLocation RParenLoc;
public:
- CXXZeroInitValueExpr(QualType ty, SourceLocation tyBeginLoc,
+ CXXScalarValueInitExpr(QualType ty, SourceLocation tyBeginLoc,
SourceLocation rParenLoc ) :
- Expr(CXXZeroInitValueExprClass, ty, false, false),
+ Expr(CXXScalarValueInitExprClass, ty, false, false),
TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
- explicit CXXZeroInitValueExpr(EmptyShell Shell)
- : Expr(CXXZeroInitValueExprClass, Shell) { }
+ explicit CXXScalarValueInitExpr(EmptyShell Shell)
+ : Expr(CXXScalarValueInitExprClass, Shell) { }
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -902,9 +908,9 @@ public:
}
static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXZeroInitValueExprClass;
+ return T->getStmtClass() == CXXScalarValueInitExprClass;
}
- static bool classof(const CXXZeroInitValueExpr *) { return true; }
+ static bool classof(const CXXScalarValueInitExpr *) { return true; }
// Iterators
virtual child_iterator child_begin();
@@ -916,15 +922,13 @@ public:
class CXXNewExpr : public Expr {
// Was the usage ::new, i.e. is the global new to be used?
bool GlobalNew : 1;
- // Was the form (type-id) used? Otherwise, it was new-type-id.
- bool ParenTypeId : 1;
// Is there an initializer? If not, built-ins are uninitialized, else they're
// value-initialized.
bool Initializer : 1;
// Do we allocate an array? If so, the first SubExpr is the size expression.
bool Array : 1;
// The number of placement new arguments.
- unsigned NumPlacementArgs : 14;
+ unsigned NumPlacementArgs : 15;
// The number of constructor arguments. This may be 1 even for non-class
// types; use the pseudo copy constructor.
unsigned NumConstructorArgs : 14;
@@ -941,12 +945,18 @@ class CXXNewExpr : public Expr {
// Must be null for all other types.
CXXConstructorDecl *Constructor;
+ /// \brief If the allocated type was expressed as a parenthesized type-id,
+ /// the source range covering the parenthesized type-id.
+ SourceRange TypeIdParens;
+
SourceLocation StartLoc;
SourceLocation EndLoc;
+ friend class PCHStmtReader;
public:
CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
- Expr **placementArgs, unsigned numPlaceArgs, bool ParenTypeId,
+ Expr **placementArgs, unsigned numPlaceArgs,
+ SourceRange TypeIdParens,
Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
Expr **constructorArgs, unsigned numConsArgs,
FunctionDecl *operatorDelete, QualType ty,
@@ -989,10 +999,11 @@ public:
return cast<Expr>(SubExprs[Array + i]);
}
+ bool isParenTypeId() const { return TypeIdParens.isValid(); }
+ SourceRange getTypeIdParens() const { return TypeIdParens; }
+
bool isGlobalNew() const { return GlobalNew; }
void setGlobalNew(bool V) { GlobalNew = V; }
- bool isParenTypeId() const { return ParenTypeId; }
- void setParenTypeId(bool V) { ParenTypeId = V; }
bool hasInitializer() const { return Initializer; }
void setHasInitializer(bool V) { Initializer = V; }
@@ -1082,18 +1093,26 @@ public:
: Expr(CXXDeleteExprClass, ty, false, false), GlobalDelete(globalDelete),
ArrayForm(arrayForm), OperatorDelete(operatorDelete), Argument(arg),
Loc(loc) { }
+ explicit CXXDeleteExpr(EmptyShell Shell)
+ : Expr(CXXDeleteExprClass, Shell), OperatorDelete(0), Argument(0) { }
bool isGlobalDelete() const { return GlobalDelete; }
bool isArrayForm() const { return ArrayForm; }
+
+ void setGlobalDelete(bool V) { GlobalDelete = V; }
+ void setArrayForm(bool V) { ArrayForm = V; }
FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+ void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
Expr *getArgument() { return cast<Expr>(Argument); }
const Expr *getArgument() const { return cast<Expr>(Argument); }
+ void setArgument(Expr *E) { Argument = E; }
virtual SourceRange getSourceRange() const {
return SourceRange(Loc, Argument->getLocEnd());
}
+ void setStartLoc(SourceLocation L) { Loc = L; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDeleteExprClass;
@@ -1215,6 +1234,10 @@ public:
ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), TildeLoc(TildeLoc),
DestroyedType(DestroyedType) { }
+ explicit CXXPseudoDestructorExpr(EmptyShell Shell)
+ : Expr(CXXPseudoDestructorExprClass, Shell),
+ Base(0), IsArrow(false), Qualifier(0), ScopeType(0) { }
+
void setBase(Expr *E) { Base = E; }
Expr *getBase() const { return cast<Expr>(Base); }
@@ -1227,11 +1250,13 @@ public:
/// the nested-name-specifier that precedes the member name. Otherwise,
/// returns an empty source range.
SourceRange getQualifierRange() const { return QualifierRange; }
+ void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// \brief If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
/// \brief Determine whether this pseudo-destructor expression was written
/// using an '->' (otherwise, it used a '.').
@@ -1240,6 +1265,7 @@ public:
/// \brief Retrieve the location of the '.' or '->' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
+ void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
/// \brief Retrieve the scope type in a qualified pseudo-destructor
/// expression.
@@ -1251,13 +1277,16 @@ public:
/// nested-name-specifier. It is stored as the "scope type" of the pseudo-
/// destructor expression.
TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
+ void setScopeTypeInfo(TypeSourceInfo *Info) { ScopeType = Info; }
/// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
/// expression.
SourceLocation getColonColonLoc() const { return ColonColonLoc; }
+ void setColonColonLoc(SourceLocation L) { ColonColonLoc = L; }
/// \brief Retrieve the location of the '~'.
SourceLocation getTildeLoc() const { return TildeLoc; }
+ void setTildeLoc(SourceLocation L) { TildeLoc = L; }
/// \brief Retrieve the source location information for the type
/// being destroyed.
@@ -1285,6 +1314,17 @@ public:
return DestroyedType.getLocation();
}
+ /// \brief Set the name of destroyed type for a dependent pseudo-destructor
+ /// expression.
+ void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) {
+ DestroyedType = PseudoDestructorTypeStorage(II, Loc);
+ }
+
+ /// \brief Set the destroyed type.
+ void setDestroyedType(TypeSourceInfo *Info) {
+ DestroyedType = PseudoDestructorTypeStorage(Info);
+ }
+
virtual SourceRange getSourceRange() const;
static bool classof(const Stmt *T) {
@@ -1321,6 +1361,9 @@ public:
: Expr(UnaryTypeTraitExprClass, ty, false, queried->isDependentType()),
UTT(utt), Loc(loc), RParen(rparen), QueriedType(queried) { }
+ explicit UnaryTypeTraitExpr(EmptyShell Empty)
+ : Expr(UnaryTypeTraitExprClass, Empty), UTT((UnaryTypeTrait)0) { }
+
virtual SourceRange getSourceRange() const { return SourceRange(Loc, RParen);}
UnaryTypeTrait getTrait() const { return UTT; }
@@ -1337,6 +1380,8 @@ public:
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class PCHStmtReader;
};
/// \brief A reference to an overloaded function set, either an
@@ -1361,16 +1406,20 @@ class OverloadExpr : public Expr {
/// The location of the name.
SourceLocation NameLoc;
+protected:
/// True if the name was a template-id.
bool HasExplicitTemplateArgs;
-protected:
OverloadExpr(StmtClass K, ASTContext &C, QualType T, bool Dependent,
NestedNameSpecifier *Qualifier, SourceRange QRange,
DeclarationName Name, SourceLocation NameLoc,
bool HasTemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+ OverloadExpr(StmtClass K, EmptyShell Empty)
+ : Expr(K, Empty), Results(0), NumResults(0),
+ Qualifier(0), HasExplicitTemplateArgs(false) { }
+
public:
/// Computes whether an unresolved lookup on the given declarations
/// and optional template arguments is type- and value-dependent.
@@ -1401,6 +1450,9 @@ public:
decls_iterator decls_end() const {
return UnresolvedSetIterator(Results + NumResults);
}
+
+ void initializeResults(ASTContext &C,
+ UnresolvedSetIterator Begin,UnresolvedSetIterator End);
/// Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return NumResults; }
@@ -1415,9 +1467,11 @@ public:
/// Fetches the nested-name qualifier, if one was given.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
/// Fetches the range of the nested-name qualifier.
SourceRange getQualifierRange() const { return QualifierRange; }
+ void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// \brief Determines whether this expression had an explicit
/// template argument list, e.g. f<int>.
@@ -1480,6 +1534,11 @@ class UnresolvedLookupExpr : public OverloadExpr {
RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
{}
+ UnresolvedLookupExpr(EmptyShell Empty)
+ : OverloadExpr(UnresolvedLookupExprClass, Empty),
+ RequiresADL(false), Overloaded(false), NamingClass(0)
+ {}
+
public:
static UnresolvedLookupExpr *Create(ASTContext &C,
bool Dependent,
@@ -1511,17 +1570,23 @@ public:
UnresolvedSetIterator Begin,
UnresolvedSetIterator End);
+ static UnresolvedLookupExpr *CreateEmpty(ASTContext &C,
+ unsigned NumTemplateArgs);
+
/// True if this declaration should be extended by
/// argument-dependent lookup.
bool requiresADL() const { return RequiresADL; }
+ void setRequiresADL(bool V) { RequiresADL = V; }
/// True if this lookup is overloaded.
bool isOverloaded() const { return Overloaded; }
+ void setOverloaded(bool V) { Overloaded = V; }
/// Gets the 'naming class' (in the sense of C++0x
/// [class.access.base]p5) of the lookup. This is the scope
/// that was looked in to find these results.
CXXRecordDecl *getNamingClass() const { return NamingClass; }
+ void setNamingClass(CXXRecordDecl *D) { NamingClass = D; }
// Note that, inconsistently with the explicit-template-argument AST
// nodes, users are *forbidden* from calling these methods on objects
@@ -1628,18 +1693,25 @@ public:
SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs = 0);
+ static DependentScopeDeclRefExpr *CreateEmpty(ASTContext &C,
+ unsigned NumTemplateArgs);
+
/// \brief Retrieve the name that this expression refers to.
DeclarationName getDeclName() const { return Name; }
+ void setDeclName(DeclarationName N) { Name = N; }
/// \brief Retrieve the location of the name within the expression.
SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
/// \brief Retrieve the source range of the nested-name-specifier.
SourceRange getQualifierRange() const { return QualifierRange; }
+ void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// \brief Retrieve the nested-name-specifier that qualifies this
/// declaration.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
/// Determines whether this lookup had explicit template arguments.
bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
@@ -1648,6 +1720,11 @@ public:
// nodes, users are *forbidden* from calling these methods on objects
// without explicit template arguments.
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1);
+ }
+
/// Gets a reference to the explicit template argument list.
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
assert(hasExplicitTemplateArgs());
@@ -1792,6 +1869,9 @@ class CXXUnresolvedConstructExpr : public Expr {
unsigned NumArgs,
SourceLocation RParenLoc);
+ CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
+ : Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) { }
+
public:
static CXXUnresolvedConstructExpr *Create(ASTContext &C,
SourceLocation TyBegin,
@@ -1801,6 +1881,9 @@ public:
unsigned NumArgs,
SourceLocation RParenLoc);
+ static CXXUnresolvedConstructExpr *CreateEmpty(ASTContext &C,
+ unsigned NumArgs);
+
/// \brief Retrieve the source location where the type begins.
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
@@ -1845,6 +1928,11 @@ public:
return *(arg_begin() + I);
}
+ void setArg(unsigned I, Expr *E) {
+ assert(I < NumArgs && "Argument index out-of-range");
+ *(arg_begin() + I) = E;
+ }
+
virtual SourceRange getSourceRange() const {
return SourceRange(TyBeginLoc, RParenLoc);
}
@@ -1908,20 +1996,6 @@ class CXXDependentScopeMemberExpr : public Expr {
/// \brief The location of the member name.
SourceLocation MemberLoc;
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name, if any.
- ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
- assert(HasExplicitTemplateArgs);
- return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
- }
-
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name, if any.
- const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
- return const_cast<CXXDependentScopeMemberExpr *>(this)
- ->getExplicitTemplateArgumentList();
- }
-
CXXDependentScopeMemberExpr(ASTContext &C,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
@@ -1960,6 +2034,9 @@ public:
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs);
+ static CXXDependentScopeMemberExpr *
+ CreateEmpty(ASTContext &C, unsigned NumTemplateArgs);
+
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
@@ -1974,6 +2051,7 @@ public:
void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
+ void setBaseType(QualType T) { BaseType = T; }
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
@@ -1987,10 +2065,12 @@ public:
/// \brief Retrieve the nested-name-specifier that qualifies the member
/// name.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
/// \brief Retrieve the source range covering the nested-name-specifier
/// that qualifies the member name.
SourceRange getQualifierRange() const { return QualifierRange; }
+ void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// \brief Retrieve the first part of the nested-name-specifier that was
/// found in the scope of the member access expression when the member access
@@ -2006,6 +2086,9 @@ public:
NamedDecl *getFirstQualifierFoundInScope() const {
return FirstQualifierFoundInScope;
}
+ void setFirstQualifierFoundInScope(NamedDecl *D) {
+ FirstQualifierFoundInScope = D;
+ }
/// \brief Retrieve the name of the member that this expression
/// refers to.
@@ -2023,6 +2106,20 @@ public:
return HasExplicitTemplateArgs;
}
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
+ assert(HasExplicitTemplateArgs);
+ return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
+ return const_cast<CXXDependentScopeMemberExpr *>(this)
+ ->getExplicitTemplateArgumentList();
+ }
+
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
@@ -2030,6 +2127,12 @@ public:
getExplicitTemplateArgumentList()->copyInto(List);
}
+ /// \brief Initializes the template arguments using the given structure.
+ void initializeTemplateArgumentsFrom(const TemplateArgumentListInfo &List) {
+ assert(HasExplicitTemplateArgs);
+ getExplicitTemplateArgumentList()->initializeFrom(List);
+ }
+
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
@@ -2127,6 +2230,10 @@ class UnresolvedMemberExpr : public OverloadExpr {
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+ UnresolvedMemberExpr(EmptyShell Empty)
+ : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
+ HasUnresolvedUsing(false), Base(0) { }
public:
static UnresolvedMemberExpr *
@@ -2140,6 +2247,9 @@ public:
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+ static UnresolvedMemberExpr *
+ CreateEmpty(ASTContext &C, unsigned NumTemplateArgs);
+
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
@@ -2158,6 +2268,12 @@ public:
void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
+ void setBaseType(QualType T) { BaseType = T; }
+
+ /// \brief Determine whether the lookup results contain an unresolved using
+ /// declaration.
+ bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
+ void setHasUnresolvedUsing(bool V) { HasUnresolvedUsing = V; }
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 79e44511d32d..def9ced94c29 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -58,67 +58,85 @@ public:
virtual ~ExternalASTSource();
- /// \brief Resolve a type ID into a type, potentially building a new
- /// type.
- virtual QualType GetType(uint32_t ID) = 0;
-
/// \brief Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
- virtual Decl *GetDecl(uint32_t ID) = 0;
+ ///
+ /// This method only needs to be implemented if the AST source ever
+ /// passes back decl sets as VisibleDeclaration objects.
+ virtual Decl *GetExternalDecl(uint32_t ID) = 0;
/// \brief Resolve a selector ID into a selector.
- virtual Selector GetSelector(uint32_t ID) = 0;
+ ///
+ /// This operation only needs to be implemented if the AST source
+ /// returns non-zero for GetNumKnownSelectors().
+ virtual Selector GetExternalSelector(uint32_t ID) = 0;
/// \brief Returns the number of selectors known to the external AST
/// source.
- virtual uint32_t GetNumKnownSelectors() = 0;
+ virtual uint32_t GetNumExternalSelectors() = 0;
- /// \brief Resolve the offset of a statement in the decl stream into a
- /// statement.
+ /// \brief Resolve the offset of a statement in the decl stream into
+ /// a statement.
///
- /// This operation will read a new statement from the external
- /// source each time it is called, and is meant to be used via a
- /// LazyOffsetPtr.
- virtual Stmt *GetDeclStmt(uint64_t Offset) = 0;
+ /// This operation is meant to be used via a LazyOffsetPtr. It only
+ /// needs to be implemented if the AST source uses methods like
+ /// FunctionDecl::setLazyBody when building decls.
+ virtual Stmt *GetExternalDeclStmt(uint64_t Offset) = 0;
- /// \brief Read all of the declarations lexically stored in a
- /// declaration context.
+ /// \brief Finds all declarations with the given name in the
+ /// given context.
///
- /// \param DC The declaration context whose declarations will be
- /// read.
+ /// Generally the final step of this method is either to call
+ /// SetExternalVisibleDeclsForName or to recursively call lookup on
+ /// the DeclContext after calling SetExternalVisibleDecls.
+ virtual DeclContext::lookup_result
+ FindExternalVisibleDeclsByName(const DeclContext *DC,
+ DeclarationName Name) = 0;
+
+ /// \brief Finds all declarations lexically contained within the given
+ /// DeclContext.
///
- /// \param Decls Vector that will contain the declarations loaded
- /// from the external source. The caller is responsible for merging
- /// these declarations with any declarations already stored in the
- /// declaration context.
- ///
- /// \returns true if there was an error while reading the
- /// declarations for this declaration context.
- virtual bool ReadDeclsLexicallyInContext(DeclContext *DC,
- llvm::SmallVectorImpl<uint32_t> &Decls) = 0;
-
- /// \brief Read all of the declarations visible from a declaration
- /// context.
- ///
- /// \param DC The declaration context whose visible declarations
- /// will be read.
- ///
- /// \param Decls A vector of visible declaration structures,
- /// providing the mapping from each name visible in the declaration
- /// context to the declaration IDs of declarations with that name.
- ///
- /// \returns true if there was an error while reading the
- /// declarations for this declaration context.
- virtual bool ReadDeclsVisibleInContext(DeclContext *DC,
- llvm::SmallVectorImpl<VisibleDeclaration> & Decls) = 0;
+ /// \return true if an error occurred
+ virtual bool FindExternalLexicalDecls(const DeclContext *DC,
+ llvm::SmallVectorImpl<Decl*> &Result) = 0;
/// \brief Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
+ ///
+ /// The default implementation of this method is a no-op.
virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
/// \brief Print any statistics that have been gathered regarding
/// the external AST source.
+ ///
+ /// The default implementation of this method is a no-op.
virtual void PrintStats();
+
+protected:
+ /// \brief Initialize the context's lookup map with the given decls.
+ /// It is assumed that none of the declarations are redeclarations of
+ /// each other.
+ static void SetExternalVisibleDecls(const DeclContext *DC,
+ const llvm::SmallVectorImpl<VisibleDeclaration> &Decls);
+
+ /// \brief Initialize the context's lookup map with the given decls.
+ /// It is assumed that none of the declarations are redeclarations of
+ /// each other.
+ static void SetExternalVisibleDecls(const DeclContext *DC,
+ const llvm::SmallVectorImpl<NamedDecl*> &Decls);
+
+ static DeclContext::lookup_result
+ SetExternalVisibleDeclsForName(const DeclContext *DC,
+ const VisibleDeclaration &VD);
+
+ static DeclContext::lookup_result
+ SetExternalVisibleDeclsForName(const DeclContext *DC,
+ DeclarationName Name,
+ llvm::SmallVectorImpl<NamedDecl*> &Decls);
+
+ static DeclContext::lookup_result
+ SetNoExternalVisibleDeclsForName(const DeclContext *DC,
+ DeclarationName Name);
};
/// \brief A lazy pointer to an AST node (of base type T) that resides
@@ -185,7 +203,8 @@ public:
};
/// \brief A lazy pointer to a statement.
-typedef LazyOffsetPtr<Stmt, &ExternalASTSource::GetDeclStmt> LazyDeclStmtPtr;
+typedef LazyOffsetPtr<Stmt, &ExternalASTSource::GetExternalDeclStmt>
+ LazyDeclStmtPtr;
} // end namespace clang
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
index a25977cad621..00a1e1bf7977 100644
--- a/include/clang/AST/Makefile
+++ b/include/clang/AST/Makefile
@@ -1,13 +1,23 @@
-LEVEL = ../../../../..
-BUILT_SOURCES = StmtNodes.inc
+CLANG_LEVEL := ../../..
+TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
+BUILT_SOURCES = Attrs.inc StmtNodes.inc DeclNodes.inc
TABLEGEN_INC_FILES_COMMON = 1
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
-INPUT_TDS = $(PROJ_SRC_DIR)/StmtNodes.td
+$(ObjDir)/Attrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang attribute classes with tblgen"
+ $(Verb) $(TableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
-$(ObjDir)/StmtNodes.inc.tmp : StmtNodes.td $(TBLGEN) $(ObjDir)/.dir
+$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(TBLGEN) \
+ $(ObjDir)/.dir
$(Echo) "Building Clang statement node tables with tblgen"
$(Verb) $(TableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $<
+$(ObjDir)/DeclNodes.inc.tmp : $(TD_SRC_DIR)/DeclNodes.td $(TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang declaration node tables with tblgen"
+ $(Verb) $(TableGen) -gen-clang-decl-nodes -o $(call SYSPATH, $@) $<
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 07865e0eb3f1..0853dddbe9e5 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -29,739 +29,1634 @@
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+
+// The following three macros are used for meta programming. The code
+// using them is responsible for defining macro OPERATOR().
+
+// All unary operators.
+#define UNARYOP_LIST() \
+ OPERATOR(PostInc) OPERATOR(PostDec) \
+ OPERATOR(PreInc) OPERATOR(PreDec) \
+ OPERATOR(AddrOf) OPERATOR(Deref) \
+ OPERATOR(Plus) OPERATOR(Minus) \
+ OPERATOR(Not) OPERATOR(LNot) \
+ OPERATOR(Real) OPERATOR(Imag) \
+ OPERATOR(Extension) OPERATOR(OffsetOf)
+
+// All binary operators (excluding compound assign operators).
+#define BINOP_LIST() \
+ OPERATOR(PtrMemD) OPERATOR(PtrMemI) \
+ OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) \
+ OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) \
+ OPERATOR(Shr) \
+ \
+ OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) \
+ OPERATOR(GE) OPERATOR(EQ) OPERATOR(NE) \
+ OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
+ OPERATOR(LAnd) OPERATOR(LOr) \
+ \
+ OPERATOR(Assign) \
+ OPERATOR(Comma)
+
+// All compound assign operators.
+#define CAO_LIST() \
+ OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
+ OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
namespace clang {
-#define DISPATCH(NAME, CLASS, Var) \
-return getDerived().Visit ## NAME(static_cast<CLASS*>(Var))
-
-// We use preprocessor meta-programming to generate the Visit*()
-// methods for all subclasses of Stmt, Decl, and Type. Some of the
-// generated definitions, however, need to be customized. The
-// meta-programming technique we use doesn't let us select which
-// methods to generate. Therefore we have to generate ALL of them in
-// a helper class RecursiveASTVisitorImpl, and override the ones we
-// don't like in a child class RecursiveASTVisitor (C++ doesn't allow
-// overriding a method in the same class).
-//
-// Do not use this class directly - use RecursiveASTVisitor instead.
+// A helper macro to implement short-circuiting when recursing. It
+// invokes CALL_EXPR, which must be a method call, on the derived
+// object (s.t. a user of RecursiveASTVisitor can override the method
+// in CALL_EXPR).
+#define TRY_TO(CALL_EXPR) \
+ do { if (!getDerived().CALL_EXPR) return false; } while (0)
+
+/// \brief A class that does preorder depth-first traversal on the
+/// entire Clang AST and visits each node.
+///
+/// This class performs three distinct tasks:
+/// 1. traverse the AST (i.e. go to each node);
+/// 2. at a given node, walk up the class hierarchy, starting from
+/// the node's dynamic type, until the top-most class (e.g. Stmt,
+/// Decl, or Type) is reached.
+/// 3. given a (node, class) combination, where 'class' is some base
+/// class of the dynamic type of 'node', call a user-overridable
+/// function to actually visit the node.
+///
+/// These tasks are done by three groups of methods, respectively:
+/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
+/// for traversing an AST rooted at x. This method simply
+/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
+/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
+/// then recursively visits the child nodes of x.
+/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
+/// similarly.
+/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
+/// any child node of x. Instead, it first calls WalkUpFromBar(x)
+/// where Bar is the direct parent class of Foo (unless Foo has
+/// no parent), and then calls VisitFoo(x) (see the next list item).
+/// 3. VisitFoo(Foo *x) does task #3.
+///
+/// These three method groups are tiered (Traverse* > WalkUpFrom* >
+/// Visit*). A method (e.g. Traverse*) may call methods from the same
+/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
+/// It may not call methods from a higher tier.
+///
+/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
+/// is Foo's super class) before calling VisitFoo(), the result is
+/// that the Visit*() methods for a given node are called in the
+/// top-down order (e.g. for a node of type NamedDecl, the order will
+/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
+///
+/// This scheme guarantees that all Visit*() calls for the same AST
+/// node are grouped together. In other words, Visit*() methods for
+/// different nodes are never interleaved.
+///
+/// Clients of this visitor should subclass the visitor (providing
+/// themselves as the template argument, using the curiously recurring
+/// template pattern) and override any of the Traverse*, WalkUpFrom*,
+/// and Visit* methods for declarations, types, statements,
+/// expressions, or other AST nodes where the visitor should customize
+/// behavior. Most users only need to override Visit*. Advanced
+/// users may override Traverse* and WalkUpFrom* to implement custom
+/// traversal strategies. Returning false from one of these overridden
+/// functions will abort the entire traversal.
template<typename Derived>
-class RecursiveASTVisitorImpl {
+class RecursiveASTVisitor {
public:
/// \brief Return a reference to the derived class.
Derived &getDerived() { return *static_cast<Derived*>(this); }
/// \brief Recursively visit a statement or expression, by
- /// dispatching to Visit*() based on the argument's dynamic type.
- /// This is NOT meant to be overridden by a subclass.
+ /// dispatching to Traverse*() based on the argument's dynamic type.
///
- /// \returns true if the visitation was terminated early, false
+ /// \returns false if the visitation was terminated early, true
/// otherwise (including when the argument is NULL).
- bool Visit(Stmt *S);
+ bool TraverseStmt(Stmt *S);
/// \brief Recursively visit a type, by dispatching to
- /// Visit*Type() based on the argument's getTypeClass() property.
- /// This is NOT meant to be overridden by a subclass.
+ /// Traverse*Type() based on the argument's getTypeClass() property.
///
- /// \returns true if the visitation was terminated early, false
+ /// \returns false if the visitation was terminated early, true
/// otherwise (including when the argument is a Null type).
- bool Visit(QualType T);
+ bool TraverseType(QualType T);
+
+ /// \brief Recursively visit a type with location, by dispatching to
+ /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is a Null type location).
+ bool TraverseTypeLoc(TypeLoc TL);
/// \brief Recursively visit a declaration, by dispatching to
- /// Visit*Decl() based on the argument's dynamic type. This is
- /// NOT meant to be overridden by a subclass.
+ /// Traverse*Decl() based on the argument's dynamic type.
///
- /// \returns true if the visitation was terminated early, false
+ /// \returns false if the visitation was terminated early, true
/// otherwise (including when the argument is NULL).
- bool Visit(Decl *D);
+ bool TraverseDecl(Decl *D);
/// \brief Recursively visit a C++ nested-name-specifier.
///
- /// \returns true if the visitation was terminated early, false otherwise.
- bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
- /// \brief Recursively visit a template name.
+ /// \brief Recursively visit a template name and dispatch to the
+ /// appropriate method.
///
- /// \returns true if the visitation was terminated early, false otherwise.
- bool VisitTemplateName(TemplateName Template);
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseTemplateName(TemplateName Template);
- /// \brief Recursively visit a template argument.
+ /// \brief Recursively visit a template argument and dispatch to the
+ /// appropriate method for the argument type.
///
- /// \returns true if the visitation was terminated early, false otherwise.
- bool VisitTemplateArgument(const TemplateArgument &Arg);
+ /// \returns false if the visitation was terminated early, true otherwise.
+ // FIXME: migrate callers to TemplateArgumentLoc instead.
+ bool TraverseTemplateArgument(const TemplateArgument &Arg);
- /// \brief Recursively visit a set of template arguments.
+ /// \brief Recursively visit a template argument location and dispatch to the
+ /// appropriate method for the argument type.
///
- /// \returns true if the visitation was terminated early, false otherwise.
- bool VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs);
-
- // If the implementation chooses not to implement a certain visit method, fall
- // back on VisitExpr or whatever else is the superclass.
-#define STMT(CLASS, PARENT) \
-bool Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT, S); }
-#include "clang/AST/StmtNodes.inc"
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
- // If the implementation doesn't implement binary operator methods, fall back
- // on VisitBinaryOperator.
-#define BINOP_FALLBACK(NAME) \
-bool VisitBin ## NAME(BinaryOperator *S) { \
-DISPATCH(BinaryOperator, BinaryOperator, S); \
-}
- BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
- BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem)
- BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl)
- BINOP_FALLBACK(Shr)
-
- BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
- BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
- BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
- BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
-
- BINOP_FALLBACK(Assign)
- BINOP_FALLBACK(Comma)
-#undef BINOP_FALLBACK
-
- // If the implementation doesn't implement compound assignment operator
- // methods, fall back on VisitCompoundAssignOperator.
-#define CAO_FALLBACK(NAME) \
-bool VisitBin ## NAME(CompoundAssignOperator *S) { \
-DISPATCH(CompoundAssignOperator, CompoundAssignOperator, S); \
-}
- CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
- CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
- CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
- CAO_FALLBACK(XorAssign)
-#undef CAO_FALLBACK
-
- // If the implementation doesn't implement unary operator methods, fall back
- // on VisitUnaryOperator.
-#define UNARYOP_FALLBACK(NAME) \
-bool VisitUnary ## NAME(UnaryOperator *S) { \
-DISPATCH(UnaryOperator, UnaryOperator, S); \
-}
- UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
- UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec)
- UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref)
-
- UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus)
- UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot)
- UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag)
- UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(OffsetOf)
-#undef UNARYOP_FALLBACK
-
- /// \brief Basis for statement and expression visitation, which
- /// visits all of the substatements and subexpressions.
+ /// \brief Recursively visit a set of template arguments.
+ /// This can be overridden by a subclass, but it's not expected that
+ /// will be needed -- this visitor always dispatches to another.
///
- /// The relation between Visit(Stmt *S) and this method is that
- /// the former dispatches to Visit*() based on S's dynamic type,
- /// which forwards the call up the inheritance chain until
- /// reaching VisitStmt(), which then calls Visit() on each
- /// substatement/subexpression.
- bool VisitStmt(Stmt *S);
-
- /// \brief Basis for type visitation, which by default does nothing.
+ /// \returns false if the visitation was terminated early, true otherwise.
+ // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
+ bool TraverseTemplateArguments(const TemplateArgument *Args,
+ unsigned NumArgs);
+
+ /// \brief Recursively visit a constructor initializer. This
+ /// automatically dispatches to another visitor for the initializer
+ /// expression, but not for the name of the initializer, so may
+ /// be overridden for clients that need access to the name.
///
- /// The relation between Visit(QualType T) and this method is
- /// that the former dispatches to Visit*Type(), which forwards the
- /// call up the inheritance chain until reaching VisitType().
- bool VisitType(Type *T);
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseConstructorInitializer(CXXBaseOrMemberInitializer *Init);
+
+ // ---- Methods on Stmts ----
-#define TYPE(Class, Base) \
- bool Visit##Class##Type(Class##Type *T);
+ // Declare Traverse*() for all concrete Stmt classes.
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) \
+ bool Traverse##CLASS(CLASS *S);
+#include "clang/AST/StmtNodes.inc"
+ // The above header #undefs ABSTRACT_STMT and STMT upon exit.
+
+ // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
+ bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
+ bool VisitStmt(Stmt *S) { return true; }
+#define STMT(CLASS, PARENT) \
+ bool WalkUpFrom##CLASS(CLASS *S) { \
+ TRY_TO(WalkUpFrom##PARENT(S)); \
+ TRY_TO(Visit##CLASS(S)); \
+ return true; \
+ } \
+ bool Visit##CLASS(CLASS *S) { return true; }
+#include "clang/AST/StmtNodes.inc"
+
+ // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+ // operator methods. Unary operators are not classes in themselves
+ // (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME) \
+ bool TraverseUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnary##NAME(S)); \
+ TRY_TO(TraverseStmt(S->getSubExpr())); \
+ return true; \
+ } \
+ bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnaryOperator(S)); \
+ TRY_TO(VisitUnary##NAME(S)); \
+ return true; \
+ } \
+ bool VisitUnary##NAME(UnaryOperator *S) { return true; }
+
+ UNARYOP_LIST()
+#undef OPERATOR
+
+ // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+ // operator methods. Binary operators are not classes in themselves
+ // (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
+ bool TraverseBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFromBin##NAME(S)); \
+ TRY_TO(TraverseStmt(S->getLHS())); \
+ TRY_TO(TraverseStmt(S->getRHS())); \
+ return true; \
+ } \
+ bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
+ TRY_TO(VisitBin##NAME(S)); \
+ return true; \
+ } \
+ bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
+
+#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
+ BINOP_LIST()
+#undef OPERATOR
+
+ // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+ // assignment methods. Compound assignment operators are not
+ // classes in themselves (they're all opcodes in
+ // CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME) \
+ GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
+
+ CAO_LIST()
+#undef OPERATOR
+#undef GENERAL_BINOP_FALLBACK
+
+ // ---- Methods on Types ----
+ // FIXME: revamp to take TypeLoc's rather than Types.
+
+ // Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE) \
+ bool Traverse##CLASS##Type(CLASS##Type *T);
+#include "clang/AST/TypeNodes.def"
+ // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
+
+ // Define WalkUpFrom*() and empty Visit*() for all Type classes.
+ bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
+ bool VisitType(Type *T) { return true; }
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
+ TRY_TO(WalkUpFrom##BASE(T)); \
+ TRY_TO(Visit##CLASS##Type(T)); \
+ return true; \
+ } \
+ bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
#include "clang/AST/TypeNodes.def"
- /// \brief Basis for declaration and definition visitation, which
- /// visits all of the subnodes.
- ///
- /// The relation between Visit(Decl *) and this method is that the
- /// former dispatches to Visit*Decl(), which forwards the call up
- /// the inheritance chain until reaching VisitDecl().
- bool VisitDecl(Decl *D);
-
-#define DECL(Class, Base) \
- bool Visit##Class##Decl(Class##Decl *D) { \
- return getDerived().Visit##Base(D); \
+ // ---- Methods on TypeLocs ----
+ // FIXME: this currently just calls the matching Type methods
+
+ // Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) \
+ bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#include "clang/AST/TypeLocNodes.def"
+ // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
+
+ // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
+ bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
+ bool VisitTypeLoc(TypeLoc TL) { return true; }
+
+ // QualifiedTypeLoc and UnqualTypeLoc are not declared in
+ // TypeNodes.def and thus need to be handled specially.
+ bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
+ return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
}
-#define ABSTRACT_DECL(Class, Base) DECL(Class, Base)
-#include "clang/AST/DeclNodes.def"
+ bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
+ bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
+ return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+ }
+ bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
+
+ // Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
+ TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
+ TRY_TO(Visit##CLASS##TypeLoc(TL)); \
+ return true; \
+ } \
+ bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+ // ---- Methods on Decls ----
+
+ // Declare Traverse*() for all concrete Decl classes.
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) \
+ bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#include "clang/AST/DeclNodes.inc"
+ // The above header #undefs ABSTRACT_DECL and DECL upon exit.
+
+ // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
+ bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
+ bool VisitDecl(Decl *D) { return true; }
+#define DECL(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
+ TRY_TO(WalkUpFrom##BASE(D)); \
+ TRY_TO(Visit##CLASS##Decl(D)); \
+ return true; \
+ } \
+ bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
+
+private:
+ // These are helper methods used by more than one Traverse* method.
+ bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
+ bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
+ unsigned Count);
+ bool TraverseRecordHelper(RecordDecl *D);
+ bool TraverseCXXRecordHelper(CXXRecordDecl *D);
+ bool TraverseDeclaratorHelper(DeclaratorDecl *D);
+ bool TraverseDeclContextHelper(DeclContext *DC);
+ bool TraverseFunctionHelper(FunctionDecl *D);
+ bool TraverseVarHelper(VarDecl *D);
};
+#define DISPATCH(NAME, CLASS, VAR) \
+ return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR))
+
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::Visit(Stmt *S) {
+bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
if (!S)
- return false;
+ return true;
// If we have a binary expr, dispatch to the subcode of the binop. A smart
// optimizer (e.g. LLVM) will fold this comparison into the switch stmt
// below.
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
- case BinaryOperator::PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator, S);
- case BinaryOperator::PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator, S);
- case BinaryOperator::Mul: DISPATCH(BinMul, BinaryOperator, S);
- case BinaryOperator::Div: DISPATCH(BinDiv, BinaryOperator, S);
- case BinaryOperator::Rem: DISPATCH(BinRem, BinaryOperator, S);
- case BinaryOperator::Add: DISPATCH(BinAdd, BinaryOperator, S);
- case BinaryOperator::Sub: DISPATCH(BinSub, BinaryOperator, S);
- case BinaryOperator::Shl: DISPATCH(BinShl, BinaryOperator, S);
- case BinaryOperator::Shr: DISPATCH(BinShr, BinaryOperator, S);
-
- case BinaryOperator::LT: DISPATCH(BinLT, BinaryOperator, S);
- case BinaryOperator::GT: DISPATCH(BinGT, BinaryOperator, S);
- case BinaryOperator::LE: DISPATCH(BinLE, BinaryOperator, S);
- case BinaryOperator::GE: DISPATCH(BinGE, BinaryOperator, S);
- case BinaryOperator::EQ: DISPATCH(BinEQ, BinaryOperator, S);
- case BinaryOperator::NE: DISPATCH(BinNE, BinaryOperator, S);
-
- case BinaryOperator::And: DISPATCH(BinAnd, BinaryOperator, S);
- case BinaryOperator::Xor: DISPATCH(BinXor, BinaryOperator, S);
- case BinaryOperator::Or : DISPATCH(BinOr, BinaryOperator, S);
- case BinaryOperator::LAnd: DISPATCH(BinLAnd, BinaryOperator, S);
- case BinaryOperator::LOr : DISPATCH(BinLOr, BinaryOperator, S);
- case BinaryOperator::Assign: DISPATCH(BinAssign, BinaryOperator, S);
- case BinaryOperator::MulAssign:
- DISPATCH(BinMulAssign, CompoundAssignOperator, S);
- case BinaryOperator::DivAssign:
- DISPATCH(BinDivAssign, CompoundAssignOperator, S);
- case BinaryOperator::RemAssign:
- DISPATCH(BinRemAssign, CompoundAssignOperator, S);
- case BinaryOperator::AddAssign:
- DISPATCH(BinAddAssign, CompoundAssignOperator, S);
- case BinaryOperator::SubAssign:
- DISPATCH(BinSubAssign, CompoundAssignOperator, S);
- case BinaryOperator::ShlAssign:
- DISPATCH(BinShlAssign, CompoundAssignOperator, S);
- case BinaryOperator::ShrAssign:
- DISPATCH(BinShrAssign, CompoundAssignOperator, S);
- case BinaryOperator::AndAssign:
- DISPATCH(BinAndAssign, CompoundAssignOperator, S);
- case BinaryOperator::OrAssign:
- DISPATCH(BinOrAssign, CompoundAssignOperator, S);
- case BinaryOperator::XorAssign:
- DISPATCH(BinXorAssign, CompoundAssignOperator, S);
- case BinaryOperator::Comma: DISPATCH(BinComma, BinaryOperator, S);
+#define OPERATOR(NAME) \
+ case BinaryOperator::NAME: DISPATCH(Bin##PtrMemD, BinaryOperator, S);
+
+ BINOP_LIST()
+#undef OPERATOR
+#undef BINOP_LIST
+
+#define OPERATOR(NAME) \
+ case BinaryOperator::NAME##Assign: \
+ DISPATCH(Bin##NAME##Assign, CompoundAssignOperator, S);
+
+ CAO_LIST()
+#undef OPERATOR
+#undef CAO_LIST
}
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
- case UnaryOperator::PostInc: DISPATCH(UnaryPostInc, UnaryOperator, S);
- case UnaryOperator::PostDec: DISPATCH(UnaryPostDec, UnaryOperator, S);
- case UnaryOperator::PreInc: DISPATCH(UnaryPreInc, UnaryOperator, S);
- case UnaryOperator::PreDec: DISPATCH(UnaryPreDec, UnaryOperator, S);
- case UnaryOperator::AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator, S);
- case UnaryOperator::Deref: DISPATCH(UnaryDeref, UnaryOperator, S);
- case UnaryOperator::Plus: DISPATCH(UnaryPlus, UnaryOperator, S);
- case UnaryOperator::Minus: DISPATCH(UnaryMinus, UnaryOperator, S);
- case UnaryOperator::Not: DISPATCH(UnaryNot, UnaryOperator, S);
- case UnaryOperator::LNot: DISPATCH(UnaryLNot, UnaryOperator, S);
- case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator, S);
- case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator, S);
- case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator, S);
- case UnaryOperator::OffsetOf: DISPATCH(UnaryOffsetOf, UnaryOperator, S);
+#define OPERATOR(NAME) \
+ case UnaryOperator::NAME: DISPATCH(Unary##NAME, UnaryOperator, S);
+
+ UNARYOP_LIST()
+#undef OPERATOR
+#undef UNARYOP_LIST
}
}
- // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+ // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
switch (S->getStmtClass()) {
case Stmt::NoStmtClass: break;
#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
-case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS, S);
+#define STMT(CLASS, PARENT) \
+ case Stmt::CLASS##Class: DISPATCH(CLASS, CLASS, S);
#include "clang/AST/StmtNodes.inc"
}
- return false;
+ return true;
}
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::Visit(QualType T) {
+bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
if (T.isNull())
- return false;
+ return true;
switch (T->getTypeClass()) {
-#define ABSTRACT_TYPE(Class, Base)
-#define TYPE(Class, Base) \
- case Type::Class: DISPATCH(Class##Type, Class##Type, T.getTypePtr());
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE) \
+ case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, T.getTypePtr());
#include "clang/AST/TypeNodes.def"
}
- return false;
+ return true;
}
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::Visit(Decl *D) {
+bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
+ if (TL.isNull())
+ return true;
+
+ switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) \
+ case TypeLoc::CLASS: \
+ return getDerived().Traverse##CLASS##TypeLoc(*cast<CLASS##TypeLoc>(&TL));
+#include "clang/AST/TypeLocNodes.def"
+ }
+
+ return true;
+}
+
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
if (!D)
- return false;
+ return true;
+
+ // As a syntax visitor, we want to ignore declarations for
+ // implicitly-defined declarations (ones not typed explicitly by the
+ // user).
+ if (D->isImplicit())
+ return true;
switch (D->getKind()) {
-#define ABSTRACT_DECL(Class, Base)
-#define DECL(Class, Base) \
- case Decl::Class: DISPATCH(Class##Decl, Class##Decl, D);
-#include "clang/AST/DeclNodes.def"
- }
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) \
+ case Decl::CLASS: DISPATCH(CLASS##Decl, CLASS##Decl, D);
+#include "clang/AST/DeclNodes.inc"
+ }
- return false;
+ return true;
}
+#undef DISPATCH
+
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitNestedNameSpecifier(
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
NestedNameSpecifier *NNS) {
- if (NNS->getPrefix() &&
- getDerived().VisitNestedNameSpecifier(NNS->getPrefix()))
+ if (!NNS)
return true;
+ if (NNS->getPrefix())
+ TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
+
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::Global:
- return false;
+ return true;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
- return Visit(QualType(NNS->getAsType(), 0));
+ TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
}
- return false;
+ return true;
}
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitTemplateName(TemplateName Template) {
+bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
- return DTN->getQualifier() &&
- getDerived().VisitNestedNameSpecifier(DTN->getQualifier());
-
- if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
- return getDerived().VisitNestedNameSpecifier(QTN->getQualifier());
+ TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
+ else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+ TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
- return false;
+ return true;
}
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitTemplateArgument(
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
const TemplateArgument &Arg) {
switch (Arg.getKind()) {
case TemplateArgument::Null:
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
- return false;
+ return true;
case TemplateArgument::Type:
- return Visit(Arg.getAsType());
+ return getDerived().TraverseType(Arg.getAsType());
case TemplateArgument::Template:
- return getDerived().VisitTemplateName(Arg.getAsTemplate());
+ return getDerived().TraverseTemplateName(Arg.getAsTemplate());
case TemplateArgument::Expression:
- return getDerived().Visit(Arg.getAsExpr());
+ return getDerived().TraverseStmt(Arg.getAsExpr());
case TemplateArgument::Pack:
- return getDerived().VisitTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
+ return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+ Arg.pack_size());
}
- return false;
+ return true;
}
+// FIXME: no template name location?
+// FIXME: no source locations for a template argument pack?
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitTemplateArguments(
- const TemplateArgument *Args,
- unsigned NumArgs) {
- for (unsigned I = 0; I != NumArgs; ++I)
- if (getDerived().VisitTemplateArgument(Args[I]))
- return true;
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
+ const TemplateArgumentLoc &ArgLoc) {
+ const TemplateArgument &Arg = ArgLoc.getArgument();
- return false;
-}
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ return true;
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitStmt(Stmt *Node) {
- for (Stmt::child_iterator C = Node->child_begin(), CEnd = Node->child_end();
- C != CEnd; ++C) {
- if (Visit(*C))
- return true;
+ case TemplateArgument::Type: {
+ TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo();
+ return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
}
- return false;
+ case TemplateArgument::Template:
+ return getDerived().TraverseTemplateName(Arg.getAsTemplate());
+
+ case TemplateArgument::Expression:
+ return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
+
+ case TemplateArgument::Pack:
+ return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+ Arg.pack_size());
+ }
+
+ return true;
}
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitType(Type *T) {
- return false;
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ for (unsigned I = 0; I != NumArgs; ++I) {
+ TRY_TO(TraverseTemplateArgument(Args[I]));
+ }
+
+ return true;
}
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitBuiltinType(BuiltinType *T) {
- return getDerived().VisitType(T);
+bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
+ CXXBaseOrMemberInitializer *Init) {
+ // FIXME: recurse on TypeLoc of the base initializer if isBaseInitializer()?
+ if (Init->isWritten())
+ TRY_TO(TraverseStmt(Init->getInit()));
+ return true;
}
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitComplexType(ComplexType *T) {
- if (Visit(T->getElementType()))
- return true;
- return getDerived().VisitType(T);
-}
+// ----------------- Type traversal -----------------
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitPointerType(PointerType *T) {
- if (Visit(T->getPointeeType()))
- return true;
+// This macro makes available a variable T, the passed-in type.
+#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
+ template<typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE (TYPE *T) { \
+ TRY_TO(WalkUpFrom##TYPE (T)); \
+ { CODE; } \
+ return true; \
+ }
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_TYPE(BuiltinType, { })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitBlockPointerType(
- BlockPointerType *T) {
- if (Visit(T->getPointeeType()))
- return true;
+DEF_TRAVERSE_TYPE(ComplexType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_TYPE(PointerType, {
+ TRY_TO(TraverseType(T->getPointeeType()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitReferenceType(ReferenceType *T) {
- if (Visit(T->getPointeeType()))
- return true;
+DEF_TRAVERSE_TYPE(BlockPointerType, {
+ TRY_TO(TraverseType(T->getPointeeType()));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_TYPE(LValueReferenceType, {
+ TRY_TO(TraverseType(T->getPointeeType()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitLValueReferenceType(
- LValueReferenceType *T) {
- return getDerived().VisitReferenceType(T);
-}
+DEF_TRAVERSE_TYPE(RValueReferenceType, {
+ TRY_TO(TraverseType(T->getPointeeType()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitRValueReferenceType(
- RValueReferenceType *T) {
- return getDerived().VisitReferenceType(T);
-}
+DEF_TRAVERSE_TYPE(MemberPointerType, {
+ TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+ TRY_TO(TraverseType(T->getPointeeType()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitMemberPointerType(
- MemberPointerType *T) {
- if (Visit(QualType(T->getClass(), 0)) || Visit(T->getPointeeType()))
- return true;
+DEF_TRAVERSE_TYPE(ConstantArrayType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_TYPE(IncompleteArrayType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitArrayType(ArrayType *T) {
- if (Visit(T->getElementType()))
- return true;
+DEF_TRAVERSE_TYPE(VariableArrayType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitConstantArrayType(
- ConstantArrayType *T) {
- return getDerived().VisitArrayType(T);
-}
+DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+ TRY_TO(TraverseType(T->getElementType()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitIncompleteArrayType(
- IncompleteArrayType *T) {
- return getDerived().VisitArrayType(T);
-}
+DEF_TRAVERSE_TYPE(VectorType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitVariableArrayType(
- VariableArrayType *T) {
- if (Visit(T->getSizeExpr()))
- return true;
+DEF_TRAVERSE_TYPE(ExtVectorType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ })
- return getDerived().VisitArrayType(T);
-}
+DEF_TRAVERSE_TYPE(FunctionNoProtoType, {
+ TRY_TO(TraverseType(T->getResultType()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedArrayType(
- DependentSizedArrayType *T) {
- if (T->getSizeExpr() && Visit(T->getSizeExpr()))
- return true;
+DEF_TRAVERSE_TYPE(FunctionProtoType, {
+ TRY_TO(TraverseType(T->getResultType()));
- return getDerived().VisitArrayType(T);
-}
+ for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
+ AEnd = T->arg_type_end();
+ A != AEnd; ++A) {
+ TRY_TO(TraverseType(*A));
+ }
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedExtVectorType(
- DependentSizedExtVectorType *T) {
- if ((T->getSizeExpr() && Visit(T->getSizeExpr())) ||
- Visit(T->getElementType()))
- return true;
+ for (FunctionProtoType::exception_iterator E = T->exception_begin(),
+ EEnd = T->exception_end();
+ E != EEnd; ++E) {
+ TRY_TO(TraverseType(*E));
+ }
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
+DEF_TRAVERSE_TYPE(TypedefType, { })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitVectorType(VectorType *T) {
- if (Visit(T->getElementType()))
- return true;
+DEF_TRAVERSE_TYPE(TypeOfExprType, {
+ TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_TYPE(TypeOfType, {
+ TRY_TO(TraverseType(T->getUnderlyingType()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitExtVectorType(ExtVectorType *T) {
- return getDerived().VisitVectorType(T);
-}
+DEF_TRAVERSE_TYPE(DecltypeType, {
+ TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitFunctionType(FunctionType *T) {
- if (Visit(T->getResultType()))
- return true;
+DEF_TRAVERSE_TYPE(RecordType, { })
+DEF_TRAVERSE_TYPE(EnumType, { })
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, { })
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
+ TRY_TO(TraverseTemplateName(T->getTemplateName()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ })
+
+DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
+
+DEF_TRAVERSE_TYPE(ElaboratedType, {
+ if (T->getQualifier()) {
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ }
+ TRY_TO(TraverseType(T->getNamedType()));
+ })
+
+DEF_TRAVERSE_TYPE(DependentNameType, {
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ })
+
+DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ })
+
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
+
+DEF_TRAVERSE_TYPE(ObjCObjectType, {
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (T->getBaseType().getTypePtr() != T)
+ TRY_TO(TraverseType(T->getBaseType()));
+ })
+
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType, {
+ TRY_TO(TraverseType(T->getPointeeType()));
+ })
+
+#undef DEF_TRAVERSE_TYPE
+
+// ----------------- TypeLoc traversal -----------------
+
+// This macro makes available a variable TL, the passed-in TypeLoc.
+// It calls WalkUpFrom* for the Type in the given TypeLoc, in addition
+// to WalkUpFrom* for the TypeLoc itself, such that existing clients
+// that override the WalkUpFrom*Type() and/or Visit*Type() methods
+// continue to work.
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
+ template<typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
+ TRY_TO(WalkUpFrom##TYPE(TL.getTypePtr())); \
+ TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
+ { CODE; } \
+ return true; \
+ }
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitFunctionNoProtoType(
- FunctionNoProtoType *T) {
- return getDerived().VisitFunctionType(T);
+bool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
+ QualifiedTypeLoc TL) {
+ // Move this over to the 'main' typeloc tree. Note that this is a
+ // move -- we pretend that we were really looking at the unqualified
+ // typeloc all along -- rather than a recursion, so we don't follow
+ // the normal CRTP plan of going through
+ // getDerived().TraverseTypeLoc. If we did, we'd be traversing
+ // twice for the same type (once as a QualifiedTypeLoc version of
+ // the type, once as an UnqualifiedTypeLoc version of the type),
+ // which in effect means we'd call VisitTypeLoc twice with the
+ // 'same' type. This solves that problem, at the cost of never
+ // seeing the qualified version of the type (unless the client
+ // subclasses TraverseQualifiedTypeLoc themselves). It's not a
+ // perfect solution. A perfect solution probably requires making
+ // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
+ // wrapper around Type* -- rather than being its own class in the
+ // type hierarchy.
+ return TraverseTypeLoc(TL.getUnqualifiedLoc());
}
+DEF_TRAVERSE_TYPELOC(BuiltinType, { })
+
+// FIXME: ComplexTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ComplexType, {
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+ })
+
+DEF_TRAVERSE_TYPELOC(PointerType, {
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(BlockPointerType, {
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(LValueReferenceType, {
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(RValueReferenceType, {
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+ })
+
+// FIXME: location of base class?
+// We traverse this in the type case as well, but how is it not reached through
+// the pointee type?
+DEF_TRAVERSE_TYPELOC(MemberPointerType, {
+ TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(VariableArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ })
+
+DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ if (TL.getTypePtr()->getSizeExpr())
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ })
+
+// FIXME: order? why not size expr first?
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
+ if (TL.getTypePtr()->getSizeExpr())
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+ })
+
+// FIXME: VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(VectorType, {
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+ })
+
+// FIXME: size and attributes
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ExtVectorType, {
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+ })
+
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
+ TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
+ })
+
+// FIXME: location of arguments, exception specifications (attributes?)
+// Note that we have the ParmVarDecl's here. Do we want to use them?
+DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
+ TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
+
+ FunctionProtoType *T = TL.getTypePtr();
+/*
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseDecl(TL.getArg(I)));
+ }
+*/
+ for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
+ AEnd = T->arg_type_end();
+ A != AEnd; ++A) {
+ TRY_TO(TraverseType(*A));
+ }
+ for (FunctionProtoType::exception_iterator E = T->exception_begin(),
+ EEnd = T->exception_end();
+ E != EEnd; ++E) {
+ TRY_TO(TraverseType(*E));
+ }
+ })
+
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { })
+DEF_TRAVERSE_TYPELOC(TypedefType, { })
+
+DEF_TRAVERSE_TYPELOC(TypeOfExprType, {
+ TRY_TO(TraverseStmt(TL.getUnderlyingExpr()));
+ })
+
+DEF_TRAVERSE_TYPELOC(TypeOfType, {
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+ })
+
+// FIXME: location of underlying expr
+DEF_TRAVERSE_TYPELOC(DecltypeType, {
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+ })
+
+DEF_TRAVERSE_TYPELOC(RecordType, { })
+DEF_TRAVERSE_TYPELOC(EnumType, { })
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { })
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { })
+
+// FIXME: use the loc for the template name?
+DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
+ TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+ })
+
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
+
+// FIXME: use the sourceloc on qualifier?
+DEF_TRAVERSE_TYPELOC(ElaboratedType, {
+ if (TL.getTypePtr()->getQualifier()) {
+ TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ }
+ TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+ })
+
+// FIXME: use the sourceloc on qualifier?
+DEF_TRAVERSE_TYPELOC(DependentNameType, {
+ TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ })
+
+DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
+ TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+ })
+
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { })
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+ TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, {
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+ })
+
+#undef DEF_TRAVERSE_TYPELOC
+
+// ----------------- Decl traversal -----------------
+//
+// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
+// the children that come from the DeclContext associated with it.
+// Therefore each Traverse* only needs to worry about children other
+// than those.
+
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitFunctionProtoType(
- FunctionProtoType *T) {
- for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
- AEnd = T->arg_type_end();
- A != AEnd; ++A) {
- if (Visit(*A))
- return true;
- }
+bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
+ if (!DC)
+ return true;
- for (FunctionProtoType::exception_iterator E = T->exception_begin(),
- EEnd = T->exception_end();
- E != EEnd; ++E) {
- if (Visit(*E))
- return true;
+ for (DeclContext::decl_iterator Child = DC->decls_begin(),
+ ChildEnd = DC->decls_end();
+ Child != ChildEnd; ++Child) {
+ TRY_TO(TraverseDecl(*Child));
}
- return getDerived().VisitFunctionType(T);
+ return true;
}
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitUnresolvedUsingType(
- UnresolvedUsingType *T) {
- return getDerived().VisitType(T);
+// This macro makes available a variable D, the passed-in decl.
+#define DEF_TRAVERSE_DECL(DECL, CODE) \
+template<typename Derived> \
+bool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) { \
+ TRY_TO(WalkUpFrom##DECL (D)); \
+ { CODE; } \
+ TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
+ return true; \
}
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitTypedefType(TypedefType *T) {
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_DECL(AccessSpecDecl, { })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfExprType(TypeOfExprType *T) {
- if (Visit(T->getUnderlyingExpr()))
- return true;
+DEF_TRAVERSE_DECL(BlockDecl, {
+ // We don't traverse nodes in param_begin()/param_end(), as they
+ // appear in decls_begin()/decls_end() and thus are handled by the
+ // DEF_TRAVERSE_DECL macro already.
+ TRY_TO(TraverseStmt(D->getBody()));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
+ TRY_TO(TraverseStmt(D->getAsmString()));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfType(TypeOfType *T) {
- if (Visit(T->getUnderlyingType()))
- return true;
+DEF_TRAVERSE_DECL(FriendDecl, {
+ TRY_TO(TraverseDecl(D->getFriendDecl()));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_DECL(FriendTemplateDecl, {
+ TRY_TO(TraverseDecl(D->getFriendDecl()));
+ for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+ TemplateParameterList *TPL = D->getTemplateParameterList(I);
+ for (TemplateParameterList::iterator ITPL = TPL->begin(),
+ ETPL = TPL->end();
+ ITPL != ETPL; ++ITPL) {
+ TRY_TO(TraverseDecl(*ITPL));
+ }
+ }
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitDecltypeType(DecltypeType *T) {
- if (Visit(T->getUnderlyingExpr()))
+DEF_TRAVERSE_DECL(LinkageSpecDecl, { })
+
+DEF_TRAVERSE_DECL(ObjCClassDecl, {
+ // FIXME: implement this
+ })
+
+DEF_TRAVERSE_DECL(ObjCForwardProtocolDecl, {
+ // FIXME: implement this
+ })
+
+DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {
+ // FIXME: implement this
+ })
+
+DEF_TRAVERSE_DECL(StaticAssertDecl, {
+ TRY_TO(TraverseStmt(D->getAssertExpr()));
+ TRY_TO(TraverseStmt(D->getMessage()));
+ })
+
+DEF_TRAVERSE_DECL(TranslationUnitDecl, {
+ // Code in an unnamed namespace shows up automatically in
+ // decls_begin()/decls_end(). Thus we don't need to recurse on
+ // D->getAnonymousNamespace().
+ })
+
+DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
+ // We shouldn't traverse an aliased namespace, since it will be
+ // defined (and, therefore, traversed) somewhere else.
+ //
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
return true;
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_DECL(NamespaceDecl, {
+ // Code in an unnamed namespace shows up automatically in
+ // decls_begin()/decls_end(). Thus we don't need to recurse on
+ // D->getAnonymousNamespace().
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitTagType(TagType *T) {
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {
+ // FIXME: implement
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitRecordType(RecordType *T) {
- return getDerived().VisitTagType(T);
-}
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
+ // FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {
+ // FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCImplementationDecl, {
+ // FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
+ // FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
+ // FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCMethodDecl, {
+ // FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
+ // FIXME: implement
+ })
+DEF_TRAVERSE_DECL(UsingDecl, {
+ TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameDecl()));
+ })
+
+DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
+ TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+ })
+
+DEF_TRAVERSE_DECL(UsingShadowDecl, { })
+
+// A helper method for TemplateDecl's children.
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitEnumType(EnumType *T) {
- return getDerived().VisitType(T);
+bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
+ TemplateParameterList *TPL) {
+ if (TPL) {
+ for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ }
+ return true;
}
+DEF_TRAVERSE_DECL(ClassTemplateDecl, {
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+ // We should not traverse the specializations/partial
+ // specializations. Those will show up in other contexts.
+ // getInstantiatedFromMemberTemplate() is just a link from a
+ // template instantiation back to the template from which it was
+ // instantiated, and thus should not be traversed either.
+ })
+
+DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+ })
+
+DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
+ // D is the "T" in something like
+ // template <template <typename> class T> class container { };
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ if (D->hasDefaultArgument()) {
+ TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
+ }
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+ })
+
+DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
+ // D is the "T" in something like "template<typename T> class vector;"
+ if (D->hasDefaultArgument())
+ TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
+ if (D->getTypeForDecl())
+ TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+ })
+
+DEF_TRAVERSE_DECL(TypedefDecl, {
+ TRY_TO(TraverseType(D->getUnderlyingType()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the typedef, not something that was written in the
+ // source.
+ })
+
+DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
+ // A dependent using declaration which was marked with 'typename'.
+ // template<class T> class A : public B<T> { using typename B<T>::foo; };
+ TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameSpecifier()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type, not something that was written in the
+ // source.
+ })
+
+DEF_TRAVERSE_DECL(EnumDecl, {
+ if (D->getTypeForDecl())
+ TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+
+ TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+ // The enumerators are already traversed by
+ // decls_begin()/decls_end().
+ })
+
+
+// Helper methods for RecordDecl and its children.
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitTemplateTypeParmType(
- TemplateTypeParmType *T) {
- return getDerived().VisitType(T);
+bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(
+ RecordDecl *D) {
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type, not something that was written in the source.
+ //
+ // The anonymous struct or union object is the variable or field
+ // whose type is the anonymous struct or union. We shouldn't
+ // traverse D->getAnonymousStructOrUnionObject(), as it's not
+ // something that is explicitly written in the source.
+ TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+ return true;
}
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitSubstTemplateTypeParmType(
- SubstTemplateTypeParmType *T) {
- return getDerived().VisitType(T);
+bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
+ CXXRecordDecl *D) {
+ if (!TraverseRecordHelper(D))
+ return false;
+ if (D->hasDefinition()) {
+ for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
+ E = D->bases_end();
+ I != E; ++I) {
+ TRY_TO(TraverseType(I->getType()));
+ }
+ // We don't traverse the friends or the conversions, as they are
+ // already in decls_begin()/decls_end().
+ }
+ return true;
}
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitTemplateSpecializationType(
- TemplateSpecializationType *T) {
- if (getDerived().VisitTemplateName(T->getTemplateName()) ||
- getDerived().VisitTemplateArguments(T->getArgs(), T->getNumArgs()))
+DEF_TRAVERSE_DECL(RecordDecl, {
+ TRY_TO(TraverseRecordHelper(D));
+ })
+
+DEF_TRAVERSE_DECL(CXXRecordDecl, {
+ TRY_TO(TraverseCXXRecordHelper(D));
+ })
+
+DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
+ // For implicit instantiations ("set<int> x;"), we don't want to
+ // recurse at all, since the instatiated class isn't written in
+ // the source code anywhere. (Note the instatiated *type* --
+ // set<int> -- is written, and will still get a callback of
+ // TemplateSpecializationType). For explicit instantiations
+ // ("template set<int>;"), we do need a callback, since this
+ // is the only callback that's made for this instantiation.
+ // We use getTypeAsWritten() to distinguish.
+ // FIXME: see how we want to handle template specializations.
+ if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
return true;
+ })
- return getDerived().VisitType(T);
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
+ const TemplateArgumentLoc *TAL, unsigned Count) {
+ for (unsigned I = 0; I < Count; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
+ }
+ return true;
}
+DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
+ // The partial specialization.
+ if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+ for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ }
+ // The args that remains unspecialized.
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ D->getTemplateArgsAsWritten(), D->getNumTemplateArgsAsWritten()));
+
+ // Don't need the ClassTemplatePartialSpecializationHelper, even
+ // though that's our parent class -- we already visit all the
+ // template args here.
+ TRY_TO(TraverseCXXRecordHelper(D));
+ })
+
+DEF_TRAVERSE_DECL(EnumConstantDecl, {
+ TRY_TO(TraverseStmt(D->getInitExpr()));
+ })
+
+DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
+ // Like UnresolvedUsingTypenameDecl, but without the 'typename':
+ // template <class T> Class A : public Base<T> { using Base<T>::foo; };
+ TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameSpecifier()));
+ })
+
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitInjectedClassNameType(
- InjectedClassNameType *T) {
- return getDerived().VisitType(T);
+bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+ TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+ if (D->getTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ return true;
}
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitElaboratedType(ElaboratedType *T) {
- if (T->getQualifier() &&
- getDerived().VisitNestedNameSpecifier(T->getQualifier()))
- return true;
- if (Visit(T->getNamedType()))
- return true;
+DEF_TRAVERSE_DECL(FieldDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ // FIXME: implement the rest.
+ })
+
+DEF_TRAVERSE_DECL(ObjCIvarDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ // FIXME: implement the rest.
+ })
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitDependentNameType(
- DependentNameType *T) {
- if (T->getQualifier() &&
- getDerived().VisitNestedNameSpecifier(T->getQualifier()))
+bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+ TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+
+ // Visit the function type itself, which can be either
+ // FunctionNoProtoType or FunctionProtoType, or a typedef. If it's
+ // not a Function*ProtoType, then it can't have a body or arguments,
+ // so we have to do less work.
+ Type *FuncType = D->getType().getTypePtr();
+ if (FunctionProtoType *FuncProto = dyn_cast<FunctionProtoType>(FuncType)) {
+ if (D->isThisDeclarationADefinition()) {
+ // Don't call Traverse*, or the result type and parameter types
+ // will be double counted.
+ TRY_TO(WalkUpFromFunctionProtoType(FuncProto));
+ } else {
+ // This works around a bug in Clang that does not add the parameters
+ // to decls_begin/end for function declarations (as opposed to
+ // definitions):
+ // http://llvm.org/PR7442
+ // We work around this here by traversing the function type.
+ // This isn't perfect because we don't traverse the default
+ // values, if any. It also may not interact great with
+ // templates. But it's the best we can do until the bug is
+ // fixed.
+ // FIXME: replace the entire 'if' statement with
+ // TRY_TO(WalkUpFromFunctionProtoType(FuncProto));
+ // when the bug is fixed.
+ TRY_TO(TraverseFunctionProtoType(FuncProto));
+ return true;
+ }
+ } else if (FunctionNoProtoType *FuncNoProto =
+ dyn_cast<FunctionNoProtoType>(FuncType)) {
+ // Don't call Traverse*, or the result type will be double
+ // counted.
+ TRY_TO(WalkUpFromFunctionNoProtoType(FuncNoProto));
+ } else { // a typedef type, or who knows what
+ assert(!D->isThisDeclarationADefinition() && "Unexpected function type");
+ TRY_TO(TraverseType(D->getType()));
return true;
+ }
- if (T->getTemplateId() &&
- getDerived().VisitTemplateSpecializationType(
- const_cast<TemplateSpecializationType *>(T->getTemplateId())))
- return true;
+ TRY_TO(TraverseType(D->getResultType()));
+ TRY_TO(TraverseDeclContextHelper(D)); // Parameters.
- return getDerived().VisitType(T);
+ if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+ // Constructor initializers.
+ for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
+ E = Ctor->init_end();
+ I != E; ++I) {
+ TRY_TO(TraverseConstructorInitializer(*I));
+ }
+ }
+
+ if (D->isThisDeclarationADefinition()) {
+ TRY_TO(TraverseStmt(D->getBody())); // Function body.
+ }
+ return true;
}
+DEF_TRAVERSE_DECL(FunctionDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+ })
+
+DEF_TRAVERSE_DECL(CXXMethodDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+ })
+
+DEF_TRAVERSE_DECL(CXXConstructorDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+ })
+
+// CXXConversionDecl is the declaration of a type conversion operator.
+// It's not a cast expression.
+DEF_TRAVERSE_DECL(CXXConversionDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+ })
+
+DEF_TRAVERSE_DECL(CXXDestructorDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+ })
+
template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitObjCInterfaceType(
- ObjCInterfaceType *T) {
- return getDerived().VisitObjCObjectType(T);
+bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ // FIXME: This often double-counts -- for instance, for all local
+ // vars, though not for global vars -- because the initializer is
+ // also captured when the var-decl is in a DeclStmt.
+ TRY_TO(TraverseStmt(D->getInit()));
+ return true;
}
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitObjCObjectType(ObjCObjectType *T) {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (T->getBaseType().getTypePtr() != T)
- if (Visit(T->getBaseType()))
- return true;
+DEF_TRAVERSE_DECL(VarDecl, {
+ TRY_TO(TraverseVarHelper(D));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_DECL(ImplicitParamDecl, {
+ TRY_TO(TraverseVarHelper(D));
+ })
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitObjCObjectPointerType(
- ObjCObjectPointerType *T) {
- if (Visit(T->getPointeeType()))
- return true;
+DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
+ // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
+ TRY_TO(TraverseStmt(D->getDefaultArgument()));
+ TRY_TO(TraverseVarHelper(D));
+ })
- return getDerived().VisitType(T);
-}
+DEF_TRAVERSE_DECL(ParmVarDecl, {
+ if (D->hasDefaultArg() &&
+ D->hasUninstantiatedDefaultArg() &&
+ !D->hasUnparsedDefaultArg())
+ TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
-template<typename Derived>
-bool RecursiveASTVisitorImpl<Derived>::VisitDecl(Decl *D) {
- if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
- for (DeclContext::decl_iterator Child = DC->decls_begin(),
- ChildEnd = DC->decls_end();
- Child != ChildEnd; ++Child)
- if (Visit(*Child))
- return true;
+ if (D->hasDefaultArg() &&
+ !D->hasUninstantiatedDefaultArg() &&
+ !D->hasUnparsedDefaultArg())
+ TRY_TO(TraverseStmt(D->getDefaultArg()));
- return false;
- }
+ TRY_TO(TraverseVarHelper(D));
+ })
- return false;
-}
+#undef DEF_TRAVERSE_DECL
-/// \brief A visitor that recursively walks the entire Clang AST.
-///
-/// Clients of this visitor should subclass the visitor (providing
-/// themselves as the template argument, using the curiously
-/// recurring template pattern) and override any of the Visit*
-/// methods (except Visit()) for declaration, type, statement,
-/// expression, or other AST nodes where the visitor should customize
-/// behavior. Returning "true" from one of these overridden functions
-/// will abort the entire traversal. An overridden Visit* method
-/// will not descend further into the AST for that node unless
-/// Base::Visit* is called.
-template<typename Derived>
-class RecursiveASTVisitor : public RecursiveASTVisitorImpl<Derived> {
- typedef RecursiveASTVisitorImpl<Derived> Impl;
-public:
- typedef RecursiveASTVisitor<Derived> Base;
-
- bool VisitDeclaratorDecl(DeclaratorDecl *D);
- bool VisitFunctionDecl(FunctionDecl *D);
- bool VisitVarDecl(VarDecl *D);
- bool VisitBlockDecl(BlockDecl *D);
- bool VisitDeclStmt(DeclStmt *S);
- bool VisitFunctionType(FunctionType *F);
- bool VisitFunctionProtoType(FunctionProtoType *F);
-};
+// ----------------- Stmt traversal -----------------
+//
+// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
+// over the children defined in child_begin/child_end (every stmt
+// defines these, though sometimes the range is empty). Each
+// individual Traverse* method only needs to worry about children
+// other than those. To see what child_begin()/end() does for a given
+// class, see, e.g.,
+// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
+
+// This macro makes available a variable S, the passed-in stmt.
+#define DEF_TRAVERSE_STMT(STMT, CODE) \
+template<typename Derived> \
+bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \
+ TRY_TO(WalkUpFrom##STMT(S)); \
+ { CODE; } \
+ for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end(); \
+ C != CEnd; ++C) { \
+ TRY_TO(TraverseStmt(*C)); \
+ } \
+ return true; \
+}
-#define DEFINE_VISIT(Type, Name, Statement) \
- template<typename Derived> \
- bool RecursiveASTVisitor<Derived>::Visit ## Type (Type *Name) { \
- if (Impl::Visit ## Type (Name)) return true; \
- { Statement; } \
- return false; \
- }
+DEF_TRAVERSE_STMT(AsmStmt, {
+ TRY_TO(TraverseStmt(S->getAsmString()));
+ for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
+ TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I)));
+ }
+ for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
+ TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I)));
+ }
+ for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
+ TRY_TO(TraverseStmt(S->getClobber(I)));
+ }
+ // child_begin()/end() iterates over inputExpr and outputExpr.
+ })
-DEFINE_VISIT(DeclaratorDecl, D, {
- if (TypeSourceInfo *TInfo = D->getTypeSourceInfo())
- return this->Visit(TInfo->getType());
+DEF_TRAVERSE_STMT(CXXCatchStmt, {
+ // We don't traverse S->getCaughtType(), as we are already
+ // traversing the exception object, which has this type.
+ // child_begin()/end() iterates over the handler block.
})
-DEFINE_VISIT(FunctionDecl, D, {
- if (D->isThisDeclarationADefinition())
- return this->Visit(D->getBody());
+DEF_TRAVERSE_STMT(ForStmt, {
+ TRY_TO(TraverseDecl(S->getConditionVariable()));
+ // child_begin()/end() iterates over init, cond, inc, and body stmts.
})
-DEFINE_VISIT(VarDecl, D, return this->Visit(D->getInit()))
+DEF_TRAVERSE_STMT(IfStmt, {
+ TRY_TO(TraverseDecl(S->getConditionVariable()));
+ // child_begin()/end() iterates over cond, then, and else stmts.
+ })
-DEFINE_VISIT(BlockDecl, D, return this->Visit(D->getBody()))
+DEF_TRAVERSE_STMT(WhileStmt, {
+ TRY_TO(TraverseDecl(S->getConditionVariable()));
+ // child_begin()/end() iterates over cond, then, and else stmts.
+ })
-DEFINE_VISIT(DeclStmt, S, {
- for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
- I != E; ++I) {
- if (this->Visit(*I))
- return true;
+// These non-expr stmts (most of them), do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BreakStmt, { })
+DEF_TRAVERSE_STMT(CompoundStmt, { })
+DEF_TRAVERSE_STMT(ContinueStmt, { })
+DEF_TRAVERSE_STMT(CXXTryStmt, { })
+DEF_TRAVERSE_STMT(DeclStmt, { })
+DEF_TRAVERSE_STMT(DoStmt, { })
+DEF_TRAVERSE_STMT(GotoStmt, { })
+DEF_TRAVERSE_STMT(IndirectGotoStmt, { })
+DEF_TRAVERSE_STMT(LabelStmt, { })
+DEF_TRAVERSE_STMT(NullStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtCatchStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
+DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
+DEF_TRAVERSE_STMT(ReturnStmt, { })
+DEF_TRAVERSE_STMT(SwitchStmt, { })
+DEF_TRAVERSE_STMT(SwitchCase, { })
+DEF_TRAVERSE_STMT(CaseStmt, { })
+DEF_TRAVERSE_STMT(DefaultStmt, { })
+
+DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ S->getTemplateArgs(), S->getNumTemplateArgs()));
}
+ TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
})
-// FunctionType is the common base class of FunctionNoProtoType (a
-// K&R-style function declaration that has no information about
-// its arguments) and FunctionProtoType.
-DEFINE_VISIT(FunctionType, F, return this->Visit(F->getResultType()))
+DEF_TRAVERSE_STMT(DeclRefExpr, {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ S->getTemplateArgs(), S->getNumTemplateArgs()));
+ // FIXME: Should we be recursing on the qualifier?
+ TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+ })
-DEFINE_VISIT(FunctionProtoType, F, {
- for (unsigned i = 0; i != F->getNumArgs(); ++i) {
- if (this->Visit(F->getArgType(i)))
- return true;
- }
- for (unsigned i = 0; i != F->getNumExceptions(); ++i) {
- if (this->Visit(F->getExceptionType(i)))
- return true;
+DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
+ // FIXME: Should we be recursing on these two things?
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ S->getExplicitTemplateArgs().getTemplateArgs(),
+ S->getNumTemplateArgs()));
}
+ TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
})
-#undef DEFINE_VISIT
+DEF_TRAVERSE_STMT(MemberExpr, {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ S->getTemplateArgs(), S->getNumTemplateArgs()));
+ // FIXME: Should we be recursing on the qualifier?
+ TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+ })
-#undef DISPATCH
+DEF_TRAVERSE_STMT(ImplicitCastExpr, {
+ // We don't traverse the cast type, as it's not written in the
+ // source code.
+ })
+
+DEF_TRAVERSE_STMT(CStyleCastExpr, {
+ TRY_TO(TraverseType(S->getTypeAsWritten()));
+ })
+
+DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
+ TRY_TO(TraverseType(S->getTypeAsWritten()));
+ })
+
+DEF_TRAVERSE_STMT(CXXConstCastExpr, {
+ TRY_TO(TraverseType(S->getTypeAsWritten()));
+ })
+
+DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
+ TRY_TO(TraverseType(S->getTypeAsWritten()));
+ })
+
+DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
+ TRY_TO(TraverseType(S->getTypeAsWritten()));
+ })
+
+DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
+ TRY_TO(TraverseType(S->getTypeAsWritten()));
+ })
+
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syntactic form of the listexpr, but this method takes the
+// semantic form by default. We can't use the macro helper because it
+// calls WalkUp*() on the semantic form, before our code can convert
+// to the syntactic form.
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
+ if (InitListExpr *Syn = S->getSyntacticForm())
+ S = Syn;
+ TRY_TO(WalkUpFromInitListExpr(S));
+ // All we need are the default actions. FIXME: use a helper function.
+ for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
+ C != CEnd; ++C) {
+ TRY_TO(TraverseStmt(*C));
+ }
+ return true;
+}
+
+DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
+ // This is called for code like 'return T()' where T is a built-in
+ // (i.e. non-class) type.
+ if (!S->isImplicit())
+ TRY_TO(TraverseType(S->getType()));
+ })
+
+DEF_TRAVERSE_STMT(CXXNewExpr, {
+ TRY_TO(TraverseType(S->getAllocatedType()));
+ })
+
+// These exprs (most of them), do not need any action except iterating
+// over the children.
+DEF_TRAVERSE_STMT(AddrLabelExpr, { })
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
+DEF_TRAVERSE_STMT(BlockDeclRefExpr, { })
+DEF_TRAVERSE_STMT(BlockExpr, { })
+DEF_TRAVERSE_STMT(ChooseExpr, { })
+DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXBindReferenceExpr, { })
+DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
+DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
+DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
+DEF_TRAVERSE_STMT(CXXExprWithTemporaries, { })
+DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { })
+DEF_TRAVERSE_STMT(CXXThisExpr, { })
+DEF_TRAVERSE_STMT(CXXThrowExpr, { })
+DEF_TRAVERSE_STMT(CXXTypeidExpr, { })
+DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { })
+DEF_TRAVERSE_STMT(DesignatedInitExpr, { })
+DEF_TRAVERSE_STMT(ExtVectorElementExpr, { })
+DEF_TRAVERSE_STMT(GNUNullExpr, { })
+DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { })
+DEF_TRAVERSE_STMT(ObjCEncodeExpr, { })
+DEF_TRAVERSE_STMT(ObjCImplicitSetterGetterRefExpr, { })
+DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
+DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
+DEF_TRAVERSE_STMT(ObjCMessageExpr, { })
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
+DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
+DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
+DEF_TRAVERSE_STMT(ObjCSuperExpr, { })
+DEF_TRAVERSE_STMT(OffsetOfExpr, { })
+DEF_TRAVERSE_STMT(ParenExpr, { })
+DEF_TRAVERSE_STMT(ParenListExpr, { })
+DEF_TRAVERSE_STMT(PredefinedExpr, { })
+DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
+DEF_TRAVERSE_STMT(SizeOfAlignOfExpr, { })
+DEF_TRAVERSE_STMT(StmtExpr, { })
+DEF_TRAVERSE_STMT(TypesCompatibleExpr, { })
+DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, { })
+DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { })
+DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { })
+DEF_TRAVERSE_STMT(VAArgExpr, { })
+DEF_TRAVERSE_STMT(CXXConstructExpr, { })
+
+DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
+ // This is called for code like 'return T()' where T is a class type.
+ TRY_TO(TraverseType(S->getType()));
+ })
+
+DEF_TRAVERSE_STMT(CallExpr, { })
+DEF_TRAVERSE_STMT(CXXMemberCallExpr, { })
+DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
+
+// These operators (all of them) do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(ConditionalOperator, { })
+DEF_TRAVERSE_STMT(UnaryOperator, { })
+DEF_TRAVERSE_STMT(BinaryOperator, { })
+DEF_TRAVERSE_STMT(CompoundAssignOperator, { })
+
+// These literals (all of them) do not need any action.
+DEF_TRAVERSE_STMT(IntegerLiteral, { })
+DEF_TRAVERSE_STMT(CharacterLiteral, { })
+DEF_TRAVERSE_STMT(FloatingLiteral, { })
+DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
+DEF_TRAVERSE_STMT(StringLiteral, { })
+DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
+
+// FIXME: look at the following tricky-seeming exprs to see if we
+// need to recurse on anything. These are ones that have methods
+// returning decls or qualtypes or nestednamespecifier -- though I'm
+// not sure if they own them -- or just seemed very complicated, or
+// had lots of sub-types to explore.
+//
+// VisitOverloadExpr and its children: recurse on template args? etc?
+
+// FIXME: go through all the stmts and exprs again, and see which of them
+// create new types, and recurse on the types (TypeLocs?) of those.
+// Candidates:
+//
+// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
+// http://clang.llvm.org/doxygen/classclang_1_1SizeOfAlignOfExpr.html
+// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
+// http://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html
+// Every class that has getQualifier.
+
+#undef DEF_TRAVERSE_STMT
+
+#undef TRY_TO
} // end namespace clang
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 01f4b29a61f4..55e1f8477992 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -92,6 +92,11 @@ public:
return D;
}
+ /// \brief Returns true if this is the first declaration.
+ bool isFirstDeclaration() const {
+ return RedeclLink.NextIsLatest();
+ }
+
/// \brief Returns the most recent (re)declaration of this declaration.
decl_type *getMostRecentDeclaration() {
return getFirstDeclaration()->RedeclLink.getNext();
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 9deae1561586..a0c95b1fce8c 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -99,11 +99,9 @@ public:
NoStmtClass = 0,
#define STMT(CLASS, PARENT) CLASS##Class,
#define STMT_RANGE(BASE, FIRST, LAST) \
- first##BASE##Constant = FIRST##Class, \
- last##BASE##Constant = LAST##Class,
+ first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
- first##BASE##Constant = FIRST##Class, \
- last##BASE##Constant = LAST##Class
+ first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
#define ABSTRACT_STMT(STMT)
#include "clang/AST/StmtNodes.inc"
};
@@ -617,24 +615,16 @@ public:
/// IfStmt - This represents an if/then/else.
///
class IfStmt : public Stmt {
- enum { COND, THEN, ELSE, END_EXPR };
+ enum { VAR, COND, THEN, ELSE, END_EXPR };
Stmt* SubExprs[END_EXPR];
- /// \brief If non-NULL, the declaration in the "if" statement.
- VarDecl *Var;
-
SourceLocation IfLoc;
SourceLocation ElseLoc;
public:
- IfStmt(SourceLocation IL, VarDecl *var, Expr *cond, Stmt *then,
- SourceLocation EL = SourceLocation(), Stmt *elsev = 0)
- : Stmt(IfStmtClass), Var(var), IfLoc(IL), ElseLoc(EL) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[THEN] = then;
- SubExprs[ELSE] = elsev;
- }
-
+ IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
+ Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0);
+
/// \brief Build an empty if/then/else statement
explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
@@ -646,8 +636,8 @@ public:
/// printf("x is %d", x);
/// }
/// \endcode
- VarDecl *getConditionVariable() const { return Var; }
- void setConditionVariable(VarDecl *V) { Var = V; }
+ VarDecl *getConditionVariable() const;
+ void setConditionVariable(ASTContext &C, VarDecl *V);
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
@@ -689,9 +679,8 @@ protected:
/// SwitchStmt - This represents a 'switch' stmt.
///
class SwitchStmt : public Stmt {
- enum { COND, BODY, END_EXPR };
+ enum { VAR, COND, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR];
- VarDecl *Var;
// This points to a linked list of case and default statements.
SwitchCase *FirstCase;
SourceLocation SwitchLoc;
@@ -700,12 +689,7 @@ protected:
virtual void DoDestroy(ASTContext &Ctx);
public:
- SwitchStmt(VarDecl *Var, Expr *cond)
- : Stmt(SwitchStmtClass), Var(Var), FirstCase(0)
- {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = NULL;
- }
+ SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond);
/// \brief Build a empty switch statement.
explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
@@ -719,8 +703,8 @@ public:
/// // ...
/// }
/// \endcode
- VarDecl *getConditionVariable() const { return Var; }
- void setConditionVariable(VarDecl *V) { Var = V; }
+ VarDecl *getConditionVariable() const;
+ void setConditionVariable(ASTContext &C, VarDecl *V);
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
const Stmt *getBody() const { return SubExprs[BODY]; }
@@ -768,18 +752,12 @@ public:
/// WhileStmt - This represents a 'while' stmt.
///
class WhileStmt : public Stmt {
- enum { COND, BODY, END_EXPR };
- VarDecl *Var;
+ enum { VAR, COND, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR];
SourceLocation WhileLoc;
public:
- WhileStmt(VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL)
- : Stmt(WhileStmtClass), Var(Var)
- {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = body;
- WhileLoc = WL;
- }
+ WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
+ SourceLocation WL);
/// \brief Build an empty while statement.
explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
@@ -792,8 +770,8 @@ public:
/// // ...
/// }
/// \endcode
- VarDecl *getConditionVariable() const { return Var; }
- void setConditionVariable(VarDecl *V) { Var = V; }
+ VarDecl *getConditionVariable() const;
+ void setConditionVariable(ASTContext &C, VarDecl *V);
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
@@ -875,23 +853,14 @@ public:
/// specified in the source.
///
class ForStmt : public Stmt {
- enum { INIT, COND, INC, BODY, END_EXPR };
+ enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
- VarDecl *CondVar;
SourceLocation ForLoc;
SourceLocation LParenLoc, RParenLoc;
public:
- ForStmt(Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, Stmt *Body,
- SourceLocation FL, SourceLocation LP, SourceLocation RP)
- : Stmt(ForStmtClass), CondVar(condVar), ForLoc(FL), LParenLoc(LP),
- RParenLoc(RP)
- {
- SubExprs[INIT] = Init;
- SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
- SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
- SubExprs[BODY] = Body;
- }
+ ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc,
+ Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP);
/// \brief Build an empty for statement.
explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
@@ -906,8 +875,8 @@ public:
/// // ...
/// }
/// \endcode
- VarDecl *getConditionVariable() const { return CondVar; }
- void setConditionVariable(VarDecl *V) { CondVar = V; }
+ VarDecl *getConditionVariable() const;
+ void setConditionVariable(ASTContext &C, VarDecl *V);
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index a48f4e69468a..4da2e3474b1c 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -16,6 +16,7 @@
#include "llvm/System/DataTypes.h"
#include <cassert>
+#include <cstddef>
#include <iterator>
namespace clang {
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 8b38001bd104..7d5123fb0449 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -256,6 +256,10 @@ public:
return Args.NumArgs;
}
+ /// Determines whether two template arguments are superficially the
+ /// same.
+ bool structurallyEquals(const TemplateArgument &Other) const;
+
/// \brief Construct a template argument pack.
void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
@@ -476,6 +480,28 @@ public:
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const TemplateArgument &Arg);
+
+inline TemplateSpecializationType::iterator
+ TemplateSpecializationType::end() const {
+ return getArgs() + getNumArgs();
+}
+
+inline DependentTemplateSpecializationType::iterator
+ DependentTemplateSpecializationType::end() const {
+ return getArgs() + getNumArgs();
+}
+
+inline const TemplateArgument &
+ TemplateSpecializationType::getArg(unsigned Idx) const {
+ assert(Idx < getNumArgs() && "Template argument out of range");
+ return getArgs()[Idx];
+}
+
+inline const TemplateArgument &
+ DependentTemplateSpecializationType::getArg(unsigned Idx) const {
+ assert(Idx < getNumArgs() && "Template argument out of range");
+ return getArgs()[Idx];
+}
} // end namespace clang
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index 2e3b6df0549b..ddfac712734b 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -101,6 +101,14 @@ class TemplateName {
}
public:
+ // \brief Kind of name that is actually stored.
+ enum NameKind {
+ Template,
+ OverloadedTemplate,
+ QualifiedTemplate,
+ DependentTemplate
+ };
+
TemplateName() : Storage() { }
explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
explicit TemplateName(OverloadedTemplateStorage *Storage)
@@ -110,6 +118,9 @@ public:
/// \brief Determine whether this template name is NULL.
bool isNull() const { return Storage.isNull(); }
+
+ // \brief Get the kind of name that is actually stored.
+ NameKind getKind() const;
/// \brief Retrieve the the underlying template declaration that
/// this template name refers to, if known.
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index c24bddb30082..a1a29e6fef6b 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -271,6 +271,8 @@ public:
}
}
+ bool isSupersetOf(Qualifiers Other) const;
+
bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
@@ -627,6 +629,14 @@ public:
bool isAtLeastAsQualifiedAs(QualType Other) const;
QualType getNonReferenceType() const;
+ /// \brief Determine the type of an expression that calls a function of
+ /// with the given result type.
+ ///
+ /// This routine removes a top-level reference (since there are no
+ /// expressions of reference type) and deletes top-level cvr-qualifiers
+ /// from non-class types (in C++) or all types (in C).
+ QualType getCallResultType(ASTContext &Context) const;
+
/// getDesugaredType - Return the specified type with any "sugar" removed from
/// the type. This takes off typedefs, typeof's etc. If the outer level of
/// the type is already concrete, it returns it unmodified. This is similar
@@ -835,6 +845,9 @@ public:
/// Helper methods to distinguish type categories. All type predicates
/// operate on the canonical type, ignoring typedefs and qualifiers.
+ /// isBuiltinType - returns true if the type is a builtin type.
+ bool isBuiltinType() const;
+
/// isSpecificBuiltinType - Test for a particular builtin type.
bool isSpecificBuiltinType(unsigned K) const;
@@ -846,8 +859,11 @@ public:
bool isCharType() const;
bool isWideCharType() const;
bool isAnyCharacterType() const;
- bool isIntegralType() const;
+ bool isIntegralType(ASTContext &Ctx) const;
+ /// \brief Determine whether this type is an integral or enumeration type.
+ bool isIntegralOrEnumerationType() const;
+
/// Floating point categories.
bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
/// isComplexType() does *not* include complex integers (a GCC extension).
@@ -923,6 +939,10 @@ public:
/// an objective pointer type for the purpose of GC'ability
bool hasObjCPointerRepresentation() const;
+ /// \brief Determine whether this type has a floating-point representation
+ /// of some sort, e.g., it is a floating-point type or a vector thereof.
+ bool hasFloatingRepresentation() const;
+
// Type Checking Functions: Check to see if this type is structurally the
// specified type, ignoring typedefs and qualifiers, and return a pointer to
// the best type we can.
@@ -1001,6 +1021,9 @@ public:
CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
void dump() const;
static bool classof(const Type *) { return true; }
+
+ friend class PCHReader;
+ friend class PCHWriter;
};
template <> inline const TypedefType *Type::getAs() const {
@@ -1640,6 +1663,13 @@ public:
/// Since the constructor takes the number of vector elements, the
/// client is responsible for converting the size into the number of elements.
class VectorType : public Type, public llvm::FoldingSetNode {
+public:
+ enum AltiVecSpecific {
+ NotAltiVec, // is not AltiVec vector
+ AltiVec, // is AltiVec vector
+ Pixel, // is AltiVec 'vector Pixel'
+ Bool // is AltiVec 'vector bool ...'
+ };
protected:
/// ElementType - The element type of the vector.
QualType ElementType;
@@ -1647,21 +1677,16 @@ protected:
/// NumElements - The number of elements in the vector.
unsigned NumElements;
- /// AltiVec - True if this is for an Altivec vector.
- bool AltiVec;
-
- /// Pixel - True if this is for an Altivec vector pixel.
- bool Pixel;
+ AltiVecSpecific AltiVecSpec;
VectorType(QualType vecType, unsigned nElements, QualType canonType,
- bool isAltiVec, bool isPixel) :
+ AltiVecSpecific altiVecSpec) :
Type(Vector, canonType, vecType->isDependentType()),
- ElementType(vecType), NumElements(nElements),
- AltiVec(isAltiVec), Pixel(isPixel) {}
+ ElementType(vecType), NumElements(nElements), AltiVecSpec(altiVecSpec) {}
VectorType(TypeClass tc, QualType vecType, unsigned nElements,
- QualType canonType, bool isAltiVec, bool isPixel)
+ QualType canonType, AltiVecSpecific altiVecSpec)
: Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
- NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
+ NumElements(nElements), AltiVecSpec(altiVecSpec) {}
friend class ASTContext; // ASTContext creates these.
virtual Linkage getLinkageImpl() const;
@@ -1674,22 +1699,18 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- bool isAltiVec() const { return AltiVec; }
-
- bool isPixel() const { return Pixel; }
-
+ AltiVecSpecific getAltiVecSpecific() const { return AltiVecSpec; }
+
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getNumElements(), getTypeClass(),
- AltiVec, Pixel);
+ Profile(ID, getElementType(), getNumElements(), getTypeClass(), AltiVecSpec);
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
unsigned NumElements, TypeClass TypeClass,
- bool isAltiVec, bool isPixel) {
+ unsigned AltiVecSpec) {
ID.AddPointer(ElementType.getAsOpaquePtr());
ID.AddInteger(NumElements);
ID.AddInteger(TypeClass);
- ID.AddBoolean(isAltiVec);
- ID.AddBoolean(isPixel);
+ ID.AddInteger(AltiVecSpec);
}
static bool classof(const Type *T) {
@@ -1705,7 +1726,7 @@ public:
/// points, colors, and textures (modeled after OpenGL Shading Language).
class ExtVectorType : public VectorType {
ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
- VectorType(ExtVector, vecType, nElements, canonType, false, false) {}
+ VectorType(ExtVector, vecType, nElements, canonType, NotAltiVec) {}
friend class ASTContext; // ASTContext creates these.
public:
static int getPointAccessorIdx(char c) {
@@ -1875,6 +1896,7 @@ protected:
public:
QualType getResultType() const { return ResultType; }
+
unsigned getRegParmType() const { return RegParm; }
bool getNoReturnAttr() const { return NoReturn; }
CallingConv getCallConv() const { return (CallingConv)CallConv; }
@@ -1882,6 +1904,12 @@ public:
return ExtInfo(NoReturn, RegParm, (CallingConv)CallConv);
}
+ /// \brief Determine the type of an expression that calls a function of
+ /// this type.
+ QualType getCallResultType(ASTContext &Context) const {
+ return getResultType().getCallResultType(Context);
+ }
+
static llvm::StringRef getNameForCallConv(CallingConv CC);
static bool classof(const Type *T) {
@@ -2416,23 +2444,14 @@ public:
/// dependent.
class TemplateSpecializationType
: public Type, public llvm::FoldingSetNode {
-
- // The ASTContext is currently needed in order to profile expressions.
- // FIXME: avoid this.
- //
- // The bool is whether this is a current instantiation.
- llvm::PointerIntPair<ASTContext*, 1, bool> ContextAndCurrentInstantiation;
-
- /// \brief The name of the template being specialized.
+ /// \brief The name of the template being specialized.
TemplateName Template;
/// \brief - The number of template arguments named in this class
/// template specialization.
unsigned NumArgs;
- TemplateSpecializationType(ASTContext &Context,
- TemplateName T,
- bool IsCurrentInstantiation,
+ TemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
unsigned NumArgs, QualType Canon);
@@ -2467,13 +2486,13 @@ public:
/// True if this template specialization type matches a current
/// instantiation in the context in which it is found.
bool isCurrentInstantiation() const {
- return ContextAndCurrentInstantiation.getInt();
+ return isa<InjectedClassNameType>(getCanonicalTypeInternal());
}
typedef const TemplateArgument * iterator;
iterator begin() const { return getArgs(); }
- iterator end() const;
+ iterator end() const; // defined inline in TemplateBase.h
/// \brief Retrieve the name of the template that we are specializing.
TemplateName getTemplateName() const { return Template; }
@@ -2488,20 +2507,18 @@ public:
/// \brief Retrieve a specific template argument as a type.
/// \precondition @c isArgType(Arg)
- const TemplateArgument &getArg(unsigned Idx) const;
+ const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
bool isSugared() const {
return !isDependentType() || isCurrentInstantiation();
}
QualType desugar() const { return getCanonicalTypeInternal(); }
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Template, isCurrentInstantiation(), getArgs(), NumArgs,
- *ContextAndCurrentInstantiation.getPointer());
+ void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Ctx) {
+ Profile(ID, Template, getArgs(), NumArgs, Ctx);
}
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
- bool IsCurrentInstantiation,
const TemplateArgument *Args,
unsigned NumArgs,
ASTContext &Context);
@@ -2545,6 +2562,9 @@ class InjectedClassNameType : public Type {
friend class ASTContext; // ASTContext creates these.
friend class TagDecl; // TagDecl mutilates the Decl
+ friend class PCHReader; // FIXME: ASTContext::getInjectedClassNameType is not
+ // currently suitable for PCH reading, too much
+ // interdependencies.
InjectedClassNameType(CXXRecordDecl *D, QualType TST)
: Type(InjectedClassName, QualType(), true),
Decl(D), InjectedType(TST) {
@@ -2679,6 +2699,7 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
public:
+ ~ElaboratedType();
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2723,11 +2744,8 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
/// \brief The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
- typedef llvm::PointerUnion<const IdentifierInfo *,
- const TemplateSpecializationType *> NameType;
-
/// \brief The type that this typename specifier refers to.
- NameType Name;
+ const IdentifierInfo *Name;
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, QualType CanonType)
@@ -2737,17 +2755,10 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
"DependentNameType requires a dependent nested-name-specifier");
}
- DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
- const TemplateSpecializationType *Ty, QualType CanonType)
- : TypeWithKeyword(Keyword, DependentName, CanonType, true),
- NNS(NNS), Name(Ty) {
- assert(NNS->isDependent() &&
- "DependentNameType requires a dependent nested-name-specifier");
- }
-
friend class ASTContext; // ASTContext creates these
public:
+ virtual ~DependentNameType();
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2759,13 +2770,7 @@ public:
/// form of the original typename was terminated by an identifier,
/// e.g., "typename T::type".
const IdentifierInfo *getIdentifier() const {
- return Name.dyn_cast<const IdentifierInfo *>();
- }
-
- /// \brief Retrieve the type named by the typename specifier as a
- /// type specialization.
- const TemplateSpecializationType *getTemplateId() const {
- return Name.dyn_cast<const TemplateSpecializationType *>();
+ return Name;
}
bool isSugared() const { return false; }
@@ -2776,10 +2781,10 @@ public:
}
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, NameType Name) {
+ NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
ID.AddInteger(Keyword);
ID.AddPointer(NNS);
- ID.AddPointer(Name.getOpaqueValue());
+ ID.AddPointer(Name);
}
static bool classof(const Type *T) {
@@ -2788,6 +2793,83 @@ public:
static bool classof(const DependentNameType *T) { return true; }
};
+/// DependentTemplateSpecializationType - Represents a template
+/// specialization type whose template cannot be resolved, e.g.
+/// A<T>::template B<T>
+class DependentTemplateSpecializationType :
+ public TypeWithKeyword, public llvm::FoldingSetNode {
+
+ /// \brief The nested name specifier containing the qualifier.
+ NestedNameSpecifier *NNS;
+
+ /// \brief The identifier of the template.
+ const IdentifierInfo *Name;
+
+ /// \brief - The number of template arguments named in this class
+ /// template specialization.
+ unsigned NumArgs;
+
+ const TemplateArgument *getArgBuffer() const {
+ return reinterpret_cast<const TemplateArgument*>(this+1);
+ }
+ TemplateArgument *getArgBuffer() {
+ return reinterpret_cast<TemplateArgument*>(this+1);
+ }
+
+ DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ unsigned NumArgs,
+ const TemplateArgument *Args,
+ QualType Canon);
+
+ virtual void Destroy(ASTContext& C);
+
+ friend class ASTContext; // ASTContext creates these
+
+public:
+ virtual ~DependentTemplateSpecializationType();
+
+ NestedNameSpecifier *getQualifier() const { return NNS; }
+ const IdentifierInfo *getIdentifier() const { return Name; }
+
+ /// \brief Retrieve the template arguments.
+ const TemplateArgument *getArgs() const {
+ return getArgBuffer();
+ }
+
+ /// \brief Retrieve the number of template arguments.
+ unsigned getNumArgs() const { return NumArgs; }
+
+ const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
+
+ typedef const TemplateArgument * iterator;
+ iterator begin() const { return getArgs(); }
+ iterator end() const; // inline in TemplateBase.h
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) {
+ Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ ASTContext &Context,
+ ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *Qualifier,
+ const IdentifierInfo *Name,
+ unsigned NumArgs,
+ const TemplateArgument *Args);
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == DependentTemplateSpecialization;
+ }
+ static bool classof(const DependentTemplateSpecializationType *T) {
+ return true;
+ }
+};
+
/// ObjCObjectType - Represents a class type in Objective C.
/// Every Objective C type is a combination of a base type and a
/// list of protocols.
@@ -3310,6 +3392,12 @@ inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
return getFunctionExtInfo(*t);
}
+/// \brief Determine whether this set of qualifiers is a superset of the given
+/// set of qualifiers.
+inline bool Qualifiers::isSupersetOf(Qualifiers Other) const {
+ return Mask != Other.Mask && (Mask | Other.Mask) == Mask;
+}
+
/// isMoreQualifiedThan - Determine whether this type is more
/// qualified than the Other type. For example, "const volatile int"
/// is more qualified than "const int", "volatile int", and
@@ -3454,6 +3542,10 @@ inline bool Type::isTemplateTypeParmType() const {
return isa<TemplateTypeParmType>(CanonicalType);
}
+inline bool Type::isBuiltinType() const {
+ return getAs<BuiltinType>();
+}
+
inline bool Type::isSpecificBuiltinType(unsigned K) const {
if (const BuiltinType *BT = getAs<BuiltinType>())
if (BT->getKind() == (BuiltinType::Kind) K)
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index f988f0e33b39..842c06878453 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -142,7 +142,7 @@ private:
/// \brief Return the TypeLoc for a type source info.
inline TypeLoc TypeSourceInfo::getTypeLoc() const {
- return TypeLoc(Ty, (void*)(this + 1));
+ return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
}
/// \brief Wrapper of type source information for a type with
@@ -657,7 +657,7 @@ struct ObjCInterfaceLocInfo {
};
/// \brief Wrapper for source info for ObjC interfaces.
-class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
ObjCInterfaceTypeLoc,
ObjCInterfaceType,
ObjCInterfaceLocInfo> {
@@ -1033,13 +1033,20 @@ public:
setLAngleLoc(Loc);
setRAngleLoc(Loc);
setTemplateNameLoc(Loc);
+ initializeArgLocs(getNumArgs(), getTypePtr()->getArgs(),
+ getArgInfos(), Loc);
+ }
- for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
+ static void initializeArgLocs(unsigned NumArgs,
+ const TemplateArgument *Args,
+ TemplateArgumentLocInfo *ArgInfos,
+ SourceLocation Loc) {
+ for (unsigned i = 0, e = NumArgs; i != e; ++i) {
TemplateArgumentLocInfo Info;
#ifndef NDEBUG
// If asserts are enabled, be sure to initialize the argument
// loc with the right kind of pointer.
- switch (getTypePtr()->getArg(i).getKind()) {
+ switch (Args[i].getKind()) {
case TemplateArgument::Expression:
case TemplateArgument::Declaration:
Info = TemplateArgumentLocInfo((Expr*) 0);
@@ -1050,7 +1057,7 @@ public:
break;
case TemplateArgument::Template:
- Info = TemplateArgumentLocInfo(SourceRange(), SourceLocation());
+ Info = TemplateArgumentLocInfo(SourceRange(Loc), Loc);
break;
case TemplateArgument::Integral:
@@ -1060,7 +1067,7 @@ public:
break;
}
#endif
- getArgInfos()[i] = Info;
+ ArgInfos[i] = Info;
}
}
@@ -1251,9 +1258,9 @@ public:
}
};
-struct DependentNameLocInfo {
- SourceLocation KeywordLoc;
- SourceRange QualifierRange;
+// This is exactly the structure of an ElaboratedTypeLoc whose inner
+// type is some sort of TypeDeclTypeLoc.
+struct DependentNameLocInfo : ElaboratedLocInfo {
SourceLocation NameLoc;
};
@@ -1303,6 +1310,107 @@ public:
}
};
+// This is exactly the structure of an ElaboratedTypeLoc whose inner
+// type is some sort of TemplateSpecializationTypeLoc.
+struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
+ // followed by a TemplateArgumentLocInfo[]
+};
+
+class DependentTemplateSpecializationTypeLoc :
+ public ConcreteTypeLoc<UnqualTypeLoc,
+ DependentTemplateSpecializationTypeLoc,
+ DependentTemplateSpecializationType,
+ DependentTemplateSpecializationLocInfo> {
+public:
+ SourceLocation getKeywordLoc() const {
+ return this->getLocalData()->KeywordLoc;
+ }
+ void setKeywordLoc(SourceLocation Loc) {
+ this->getLocalData()->KeywordLoc = Loc;
+ }
+
+ SourceRange getQualifierRange() const {
+ return this->getLocalData()->QualifierRange;
+ }
+ void setQualifierRange(SourceRange Range) {
+ this->getLocalData()->QualifierRange = Range;
+ }
+
+ SourceLocation getNameLoc() const {
+ return this->getLocalData()->NameLoc;
+ }
+ void setNameLoc(SourceLocation Loc) {
+ this->getLocalData()->NameLoc = Loc;
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return this->getLocalData()->LAngleLoc;
+ }
+ void setLAngleLoc(SourceLocation Loc) {
+ this->getLocalData()->LAngleLoc = Loc;
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return this->getLocalData()->RAngleLoc;
+ }
+ void setRAngleLoc(SourceLocation Loc) {
+ this->getLocalData()->RAngleLoc = Loc;
+ }
+
+ unsigned getNumArgs() const {
+ return getTypePtr()->getNumArgs();
+ }
+
+ void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
+#ifndef NDEBUG
+ AI.validateForArgument(getTypePtr()->getArg(i));
+#endif
+ getArgInfos()[i] = AI;
+ }
+ TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
+ return getArgInfos()[i];
+ }
+
+ TemplateArgumentLoc getArgLoc(unsigned i) const {
+ return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+ }
+
+ SourceRange getLocalSourceRange() const {
+ if (getKeywordLoc().isValid())
+ return SourceRange(getKeywordLoc(), getRAngleLoc());
+ else
+ return SourceRange(getQualifierRange().getBegin(), getRAngleLoc());
+ }
+
+ void copy(DependentTemplateSpecializationTypeLoc Loc) {
+ unsigned size = getFullDataSize();
+ assert(size == Loc.getFullDataSize());
+ memcpy(Data, Loc.Data, size);
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setKeywordLoc(Loc);
+ setQualifierRange(SourceRange(Loc));
+ setNameLoc(Loc);
+ setLAngleLoc(Loc);
+ setRAngleLoc(Loc);
+ TemplateSpecializationTypeLoc::initializeArgLocs(getNumArgs(),
+ getTypePtr()->getArgs(),
+ getArgInfos(), Loc);
+ }
+
+ unsigned getExtraLocalDataSize() const {
+ return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+ }
+
+private:
+ TemplateArgumentLocInfo *getArgInfos() const {
+ return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+ }
+};
+
}
#endif
diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h
index e729488e4313..880af267f324 100644
--- a/include/clang/AST/TypeLocBuilder.h
+++ b/include/clang/AST/TypeLocBuilder.h
@@ -79,7 +79,14 @@ class TypeLocBuilder {
size_t LocalSize = TypeSpecTypeLoc::LocalDataSize;
return cast<TypeSpecTypeLoc>(pushImpl(T, LocalSize));
}
-
+
+ /// Resets this builder to the newly-initialized state.
+ void clear() {
+#ifndef NDEBUG
+ LastTy = QualType();
+#endif
+ Index = Capacity;
+ }
/// Pushes space for a new TypeLoc of the given type. Invalidates
/// any TypeLocs previously retrieved from this builder.
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 02508af67dd8..9cb56861a9ef 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -92,6 +92,7 @@ NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
+DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
TYPE(ObjCObject, Type)
TYPE(ObjCInterface, ObjCObjectType)
TYPE(ObjCObjectPointer, Type)
diff --git a/include/clang/AST/UsuallyTinyPtrVector.h b/include/clang/AST/UsuallyTinyPtrVector.h
index 5ee40e05c956..534d4d4a367f 100644
--- a/include/clang/AST/UsuallyTinyPtrVector.h
+++ b/include/clang/AST/UsuallyTinyPtrVector.h
@@ -41,6 +41,7 @@ public:
typedef const T **iterator;
iterator begin() const;
iterator end() const;
+ size_t size() const;
void push_back(T *Method);
void Destroy();
@@ -56,7 +57,6 @@ UsuallyTinyPtrVector<T>::begin() const {
return &Vec->front();
}
-
template<typename T>
typename UsuallyTinyPtrVector<T>::iterator
UsuallyTinyPtrVector<T>::end() const {
@@ -72,6 +72,15 @@ UsuallyTinyPtrVector<T>::end() const {
}
template<typename T>
+size_t UsuallyTinyPtrVector<T>::size() const {
+ if ((Storage & 0x01) == 0)
+ return (Storage == 0) ? 0 : 1;
+
+ vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+ return Vec->size();
+}
+
+template<typename T>
void UsuallyTinyPtrVector<T>::push_back(T *Element) {
if (Storage == 0) {
// 0 -> 1 element.
diff --git a/include/clang/Analysis/Analyses/PrintfFormatString.h b/include/clang/Analysis/Analyses/PrintfFormatString.h
index e4f7c57061d4..d907637d39c5 100644
--- a/include/clang/Analysis/Analyses/PrintfFormatString.h
+++ b/include/clang/Analysis/Analyses/PrintfFormatString.h
@@ -25,8 +25,8 @@ namespace analyze_printf {
class ArgTypeResult {
public:
- enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CStrTy,
- WCStrTy };
+ enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
+ CStrTy, WCStrTy };
private:
const Kind K;
QualType T;
@@ -57,6 +57,7 @@ public:
InvalidSpecifier = 0,
// C99 conversion specifiers.
dArg, // 'd'
+ IntAsCharArg, // 'c'
iArg, // 'i',
oArg, // 'o',
uArg, // 'u',
@@ -70,7 +71,6 @@ public:
GArg, // 'G',
aArg, // 'a',
AArg, // 'A',
- IntAsCharArg, // 'c'
CStrArg, // 's'
VoidPtrArg, // 'p'
OutIntPtrArg, // 'n'
@@ -124,45 +124,87 @@ public:
bool isUIntArg() const { return kind >= oArg && kind <= XArg; }
bool isDoubleArg() const { return kind >= fArg && kind <= AArg; }
Kind getKind() const { return kind; }
+ void setKind(Kind k) { kind = k; }
unsigned getLength() const {
// Conversion specifiers currently only are represented by
// single characters, but we be flexible.
return 1;
}
+ const char *toString() const;
private:
const char *Position;
Kind kind;
};
-enum LengthModifier {
- None,
- AsChar, // 'hh'
- AsShort, // 'h'
- AsLong, // 'l'
- AsLongLong, // 'll', 'q' (BSD, deprecated)
- AsIntMax, // 'j'
- AsSizeT, // 'z'
- AsPtrDiff, // 't'
- AsLongDouble, // 'L'
- AsWideChar = AsLong // for '%ls'
+class LengthModifier {
+public:
+ enum Kind {
+ None,
+ AsChar, // 'hh'
+ AsShort, // 'h'
+ AsLong, // 'l'
+ AsLongLong, // 'll', 'q' (BSD, deprecated)
+ AsIntMax, // 'j'
+ AsSizeT, // 'z'
+ AsPtrDiff, // 't'
+ AsLongDouble, // 'L'
+ AsWideChar = AsLong // for '%ls'
+ };
+
+ LengthModifier()
+ : Position(0), kind(None) {}
+ LengthModifier(const char *pos, Kind k)
+ : Position(pos), kind(k) {}
+
+ const char *getStart() const {
+ return Position;
+ }
+
+ unsigned getLength() const {
+ switch (kind) {
+ default:
+ return 1;
+ case AsLongLong:
+ case AsChar:
+ return 2;
+ case None:
+ return 0;
+ }
+ }
+
+ Kind getKind() const { return kind; }
+ void setKind(Kind k) { kind = k; }
+
+ const char *toString() const;
+
+private:
+ const char *Position;
+ Kind kind;
};
class OptionalAmount {
public:
enum HowSpecified { NotSpecified, Constant, Arg, Invalid };
- OptionalAmount(HowSpecified h, unsigned i, const char *st)
- : start(st), hs(h), amt(i) {}
+ OptionalAmount(HowSpecified howSpecified,
+ unsigned amount,
+ const char *amountStart,
+ unsigned amountLength,
+ bool usesPositionalArg)
+ : start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
+ UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
- OptionalAmount(bool b = true)
- : start(0), hs(b ? NotSpecified : Invalid), amt(0) {}
+ OptionalAmount(bool valid = true)
+ : start(0),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
+ UsesPositionalArg(0), UsesDotPrefix(0) {}
bool isInvalid() const {
return hs == Invalid;
}
HowSpecified getHowSpecified() const { return hs; }
+ void setHowSpecified(HowSpecified h) { hs = h; }
bool hasDataArgument() const { return hs == Arg; }
@@ -177,36 +219,87 @@ public:
}
const char *getStart() const {
- return start;
+ // We include the . character if it is given.
+ return start - UsesDotPrefix;
+ }
+
+ unsigned getConstantLength() const {
+ assert(hs == Constant);
+ return length + UsesDotPrefix;
}
ArgTypeResult getArgType(ASTContext &Ctx) const;
+ void toString(llvm::raw_ostream &os) const;
+
+ bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
+ unsigned getPositionalArgIndex() const {
+ assert(hasDataArgument());
+ return amt + 1;
+ }
+
+ bool usesDotPrefix() const { return UsesDotPrefix; }
+ void setUsesDotPrefix() { UsesDotPrefix = true; }
+
private:
const char *start;
+ unsigned length;
HowSpecified hs;
unsigned amt;
+ bool UsesPositionalArg : 1;
+ bool UsesDotPrefix;
+};
+
+// Class representing optional flags with location and representation
+// information.
+class OptionalFlag {
+public:
+ OptionalFlag(const char *Representation)
+ : representation(Representation), flag(false) {}
+ bool isSet() { return flag; }
+ void set() { flag = true; }
+ void clear() { flag = false; }
+ void setPosition(const char *position) {
+ assert(position);
+ this->position = position;
+ }
+ const char *getPosition() const {
+ assert(position);
+ return position;
+ }
+ const char *toString() const { return representation; }
+
+ // Overloaded operators for bool like qualities
+ operator bool() const { return flag; }
+ OptionalFlag& operator=(const bool &rhs) {
+ flag = rhs;
+ return *this; // Return a reference to myself.
+ }
+private:
+ const char *representation;
+ const char *position;
+ bool flag;
};
class FormatSpecifier {
LengthModifier LM;
- unsigned IsLeftJustified : 1;
- unsigned HasPlusPrefix : 1;
- unsigned HasSpacePrefix : 1;
- unsigned HasAlternativeForm : 1;
- unsigned HasLeadingZeroes : 1;
+ OptionalFlag IsLeftJustified; // '-'
+ OptionalFlag HasPlusPrefix; // '+'
+ OptionalFlag HasSpacePrefix; // ' '
+ OptionalFlag HasAlternativeForm; // '#'
+ OptionalFlag HasLeadingZeroes; // '0'
/// Positional arguments, an IEEE extension:
/// IEEE Std 1003.1, 2004 Edition
/// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
- unsigned UsesPositionalArg : 1;
+ bool UsesPositionalArg;
unsigned argIndex;
ConversionSpecifier CS;
OptionalAmount FieldWidth;
OptionalAmount Precision;
public:
- FormatSpecifier() : LM(None),
- IsLeftJustified(0), HasPlusPrefix(0), HasSpacePrefix(0),
- HasAlternativeForm(0), HasLeadingZeroes(0), UsesPositionalArg(0),
+ FormatSpecifier() :
+ IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "),
+ HasAlternativeForm("#"), HasLeadingZeroes("0"), UsesPositionalArg(false),
argIndex(0) {}
static FormatSpecifier Parse(const char *beg, const char *end);
@@ -218,12 +311,27 @@ public:
void setLengthModifier(LengthModifier lm) {
LM = lm;
}
- void setIsLeftJustified() { IsLeftJustified = 1; }
- void setHasPlusPrefix() { HasPlusPrefix = 1; }
- void setHasSpacePrefix() { HasSpacePrefix = 1; }
- void setHasAlternativeForm() { HasAlternativeForm = 1; }
- void setHasLeadingZeros() { HasLeadingZeroes = 1; }
- void setUsesPositionalArg() { UsesPositionalArg = 1; }
+ void setIsLeftJustified(const char *position) {
+ IsLeftJustified = true;
+ IsLeftJustified.setPosition(position);
+ }
+ void setHasPlusPrefix(const char *position) {
+ HasPlusPrefix = true;
+ HasPlusPrefix.setPosition(position);
+ }
+ void setHasSpacePrefix(const char *position) {
+ HasSpacePrefix = true;
+ HasSpacePrefix.setPosition(position);
+ }
+ void setHasAlternativeForm(const char *position) {
+ HasAlternativeForm = true;
+ HasAlternativeForm.setPosition(position);
+ }
+ void setHasLeadingZeros(const char *position) {
+ HasLeadingZeroes = true;
+ HasLeadingZeroes.setPosition(position);
+ }
+ void setUsesPositionalArg() { UsesPositionalArg = true; }
void setArgIndex(unsigned i) {
assert(CS.consumesDataArgument());
@@ -235,13 +343,18 @@ public:
return argIndex;
}
+ unsigned getPositionalArgIndex() const {
+ assert(CS.consumesDataArgument());
+ return argIndex + 1;
+ }
+
// Methods for querying the format specifier.
const ConversionSpecifier &getConversionSpecifier() const {
return CS;
}
- LengthModifier getLengthModifier() const {
+ const LengthModifier &getLengthModifier() const {
return LM;
}
@@ -255,6 +368,7 @@ public:
void setPrecision(const OptionalAmount &Amt) {
Precision = Amt;
+ Precision.setUsesDotPrefix();
}
const OptionalAmount &getPrecision() const {
@@ -268,12 +382,30 @@ public:
/// more than one type.
ArgTypeResult getArgType(ASTContext &Ctx) const;
- bool isLeftJustified() const { return (bool) IsLeftJustified; }
- bool hasPlusPrefix() const { return (bool) HasPlusPrefix; }
- bool hasAlternativeForm() const { return (bool) HasAlternativeForm; }
- bool hasLeadingZeros() const { return (bool) HasLeadingZeroes; }
- bool hasSpacePrefix() const { return (bool) HasSpacePrefix; }
- bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
+ const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
+ const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
+ const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
+ const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
+ const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
+ bool usesPositionalArg() const { return UsesPositionalArg; }
+
+ /// Changes the specifier and length according to a QualType, retaining any
+ /// flags or options. Returns true on success, or false when a conversion
+ /// was not successful.
+ bool fixType(QualType QT);
+
+ void toString(llvm::raw_ostream &os) const;
+
+ // Validation methods - to check if any element results in undefined behavior
+ bool hasValidPlusPrefix() const;
+ bool hasValidAlternativeForm() const;
+ bool hasValidLeadingZeros() const;
+ bool hasValidSpacePrefix() const;
+ bool hasValidLeftJustified() const;
+
+ bool hasValidLengthModifier() const;
+ bool hasValidPrecision() const;
+ bool hasValidFieldWidth() const;
};
enum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 };
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index c6c9eedcbf09..7cd481238f81 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include <algorithm>
#include <cstring>
+#include <memory>
namespace clang {
diff --git a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
index d627b88967f2..f20a49a6fcd8 100644
--- a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
+++ b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
@@ -22,13 +22,14 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclCXX.h"
-#define DISPATCH_CASE(CASE,CLASS) \
-case Decl::CASE: \
-static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<CLASS*>(D));\
+#define DISPATCH_CASE(CLASS) \
+case Decl::CLASS: \
+static_cast<ImplClass*>(this)->Visit##CLASS##Decl( \
+ static_cast<CLASS##Decl*>(D)); \
break;
-#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS(CLASS* D) {}
-#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS(CLASS* D)\
+#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS##Decl(CLASS##Decl* D) {}
+#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS##Decl(CLASS##Decl* D)\
{ static_cast<ImplClass*>(this)->VisitVarDecl(D); }
@@ -55,34 +56,39 @@ public:
void VisitDecl(Decl* D) {
switch (D->getKind()) {
- DISPATCH_CASE(Function,FunctionDecl)
- DISPATCH_CASE(CXXMethod,CXXMethodDecl)
- DISPATCH_CASE(Var,VarDecl)
- DISPATCH_CASE(ParmVar,ParmVarDecl) // FIXME: (same)
- DISPATCH_CASE(ImplicitParam,ImplicitParamDecl)
- DISPATCH_CASE(EnumConstant,EnumConstantDecl)
- DISPATCH_CASE(Typedef,TypedefDecl)
- DISPATCH_CASE(Record,RecordDecl) // FIXME: Refine. VisitStructDecl?
- DISPATCH_CASE(Enum,EnumDecl)
+ DISPATCH_CASE(Function)
+ DISPATCH_CASE(CXXMethod)
+ DISPATCH_CASE(Var)
+ DISPATCH_CASE(ParmVar) // FIXME: (same)
+ DISPATCH_CASE(ImplicitParam)
+ DISPATCH_CASE(EnumConstant)
+ DISPATCH_CASE(Typedef)
+ DISPATCH_CASE(Record) // FIXME: Refine. VisitStructDecl?
+ DISPATCH_CASE(CXXRecord)
+ DISPATCH_CASE(Enum)
default:
assert(false && "Subtype of ScopedDecl not handled.");
}
}
- DEFAULT_DISPATCH(VarDecl)
- DEFAULT_DISPATCH(FunctionDecl)
- DEFAULT_DISPATCH(CXXMethodDecl)
- DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
- DEFAULT_DISPATCH(ImplicitParamDecl)
- DEFAULT_DISPATCH(EnumConstantDecl)
- DEFAULT_DISPATCH(TypedefDecl)
- DEFAULT_DISPATCH(RecordDecl)
- DEFAULT_DISPATCH(EnumDecl)
- DEFAULT_DISPATCH(ObjCInterfaceDecl)
- DEFAULT_DISPATCH(ObjCClassDecl)
- DEFAULT_DISPATCH(ObjCMethodDecl)
- DEFAULT_DISPATCH(ObjCProtocolDecl)
- DEFAULT_DISPATCH(ObjCCategoryDecl)
+ DEFAULT_DISPATCH(Var)
+ DEFAULT_DISPATCH(Function)
+ DEFAULT_DISPATCH(CXXMethod)
+ DEFAULT_DISPATCH_VARDECL(ParmVar)
+ DEFAULT_DISPATCH(ImplicitParam)
+ DEFAULT_DISPATCH(EnumConstant)
+ DEFAULT_DISPATCH(Typedef)
+ DEFAULT_DISPATCH(Record)
+ DEFAULT_DISPATCH(Enum)
+ DEFAULT_DISPATCH(ObjCInterface)
+ DEFAULT_DISPATCH(ObjCClass)
+ DEFAULT_DISPATCH(ObjCMethod)
+ DEFAULT_DISPATCH(ObjCProtocol)
+ DEFAULT_DISPATCH(ObjCCategory)
+
+ void VisitCXXRecordDecl(CXXRecordDecl *D) {
+ static_cast<ImplClass*>(this)->VisitRecordDecl(D);
+ }
};
} // end namespace clang
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
new file mode 100644
index 000000000000..98871d26204f
--- /dev/null
+++ b/include/clang/Basic/Attr.td
@@ -0,0 +1,382 @@
+////////////////////////////////////////////////////////////////////////////////
+// Note: This file is a work in progress. Please do not apply non-trivial
+// updates unless you have talked to Sean Hunt <rideau3@gmail.com> prior.
+// Merely adding a new attribute is a trivial update.
+////////////////////////////////////////////////////////////////////////////////
+
+// An attribute's subject is whatever it appertains to. In this file, it is
+// more accurately a list of things that an attribute can appertain to. All
+// Decls and Stmts are possibly AttrSubjects (even though the syntax may not
+// allow attributes on a given Decl or Stmt).
+class AttrSubject;
+
+include "clang/Basic/DeclNodes.td"
+include "clang/Basic/StmtNodes.td"
+
+// A subset-subject is an AttrSubject constrained to operate only on some subset
+// of that subject.
+//
+// The description is used in output messages to specify what the subject
+// represents. FIXME: Deal with translation issues.
+//
+// The code fragment is a boolean expression that will confirm that the subject
+// meets the requirements; the subject will have the name S, and will have the
+// type specified by the base. It should be a simple boolean expression.
+class SubsetSubject<AttrSubject base, string description, code check>
+ : AttrSubject {
+ AttrSubject Base = base;
+ string Description = description;
+ code CheckCode = check;
+}
+
+// This is the type of a variable which C++0x defines [[aligned()]] as being
+// a possible subject.
+def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable",
+ [{S->getStorageClass() != VarDecl::Register &&
+ S->getKind() != Decl::ImplicitParam
+ S->getKind() != Decl::ParmVar
+ S->getKind() != Decl::NonTypeTemplateParm}]>;
+def CXXVirtualMethod : SubsetSubject<CXXRecord, "virtual member function",
+ [{S->isVirtual()}]>;
+def NonBitField : SubsetSubject<Field, "non-bit field",
+ [{!S->isBitField()}]>;
+
+// A single argument to an attribute
+class Argument<string name> {
+ string Name = name;
+}
+
+class IdentifierArgument<string name> : Argument<name>;
+class IntArgument<string name> : Argument<name>;
+class StringArgument<string name> : Argument<name>;
+class ExprArgument<string name> : Argument<name>;
+class FunctionArgument<string name> : Argument<name>;
+class ObjCInterfaceArgument<string name> : Argument<name>;
+class UnsignedIntArgument<string name> : Argument<name>;
+class UnsignedIntOrTypeArgument<string name> : Argument<name>;
+
+// An integer argument with a default value
+class DefaultIntArgument<string name, int default> : IntArgument<name> {
+ int Default = default;
+}
+
+// Zero or more arguments of a type
+class VariadicArgument<Argument arg> : Argument<arg.Name> {
+ Argument VariadicArg = arg;
+}
+
+class Attr {
+ // The various ways in which an attribute can be spelled in source
+ list<string> Spellings;
+ // The things to which an attribute can appertain
+ list<AttrSubject> Subjects;
+ // The arguments allowed on an attribute
+ list<Argument> Args = [];
+ // The namespaces in which the attribute appears in C++0x attributes.
+ // The attribute will not be permitted in C++0x attribute-specifiers if
+ // this is empty; the empty string can be used as a namespace.
+ list<string> Namespaces = [];
+ // A temporary development bit to tell TableGen not to emit certain
+ // information about the attribute.
+ bit DoNotEmit = 1;
+}
+
+//
+// Attributes begin here
+//
+
+def Alias : Attr {
+ let Spellings = ["alias"];
+ let Args = [StringArgument<"AliasName">];
+}
+
+def Aligned : Attr {
+ let Spellings = ["align", "aligned"];
+ let Subjects = [NonBitField, NormalVar, Tag];
+ let Args = [UnsignedIntOrTypeArgument<"Alignment">];
+ let Namespaces = ["", "std"];
+}
+
+def AlignMac68k : Attr {
+ let Spellings = [];
+}
+
+def AlwaysInline : Attr {
+ let Spellings = ["always_inline"];
+}
+
+def AnalyzerNoReturn : Attr {
+ let Spellings = ["analyzer_noreturn"];
+}
+
+def Annotate : Attr {
+ let Spellings = ["annotate"];
+ let Args = [StringArgument<"Annotation">];
+}
+
+def AsmLabel : Attr {
+ let Spellings = [];
+ let Args = [StringArgument<"Label">];
+}
+
+def BaseCheck : Attr {
+ let Spellings = ["base_check"];
+ let Subjects = [CXXRecord];
+ let Namespaces = ["", "std"];
+ let DoNotEmit = 0;
+}
+
+def Blocks : Attr {
+ let Spellings = ["blocks"];
+ let Args = [IdentifierArgument<"Type">];
+}
+
+def CarriesDependency : Attr {
+ let Spellings = ["carries_dependency"];
+ let Subjects = [ParmVar, Function];
+ let Namespaces = ["", "std"];
+ let DoNotEmit = 0;
+}
+
+def CDecl : Attr {
+ let Spellings = ["cdecl", "__cdecl"];
+}
+
+def CFReturnsRetained : Attr {
+ let Spellings = ["cf_returns_retained"];
+}
+
+def CFReturnsNotRetained : Attr {
+ let Spellings = ["cf_returns_not_retained"];
+}
+
+def Cleanup : Attr {
+ let Spellings = ["cleanup"];
+ let Args = [FunctionArgument<"FunctionDecl">];
+}
+
+def Const : Attr {
+ let Spellings = ["const"];
+}
+
+def Constructor : Attr {
+ let Spellings = ["constructor"];
+ let Args = [IntArgument<"Priority">];
+}
+
+def Deprecated : Attr {
+ let Spellings = ["deprecated"];
+}
+
+def Destructor : Attr {
+ let Spellings = ["destructor"];
+ let Args = [IntArgument<"Priority">];
+}
+
+def DLLExport : Attr {
+ let Spellings = ["dllexport"];
+}
+
+def DLLImport : Attr {
+ let Spellings = ["dllimport"];
+}
+
+def FastCall : Attr {
+ let Spellings = ["fastcall", "__fastcall"];
+}
+
+def Final : Attr {
+ let Spellings = ["final"];
+ let Subjects = [CXXRecord, CXXVirtualMethod];
+ let Namespaces = ["", "std"];
+ let DoNotEmit = 0;
+}
+
+def Format : Attr {
+ let Spellings = ["format"];
+ let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
+ IntArgument<"FirstArg">];
+}
+
+def FormatArg : Attr {
+ let Spellings = ["format_arg"];
+ let Args = [IntArgument<"FormatIdx">];
+}
+
+def GNUInline : Attr {
+ let Spellings = ["gnu_inline"];
+}
+
+def Hiding : Attr {
+ let Spellings = ["hiding"];
+ let Subjects = [Field, CXXMethod];
+ let Namespaces = ["", "std"];
+ let DoNotEmit = 0;
+}
+
+def IBAction : Attr {
+ let Spellings = ["ibaction"];
+}
+
+def IBOutlet : Attr {
+ let Spellings = ["iboutlet"];
+}
+
+def IBOutletCollection : Attr {
+ let Spellings = ["iboutletcollection"];
+ let Args = [ObjCInterfaceArgument<"Class">];
+}
+
+def Malloc : Attr {
+ let Spellings = ["malloc"];
+}
+
+def MaxFieldAlignment : Attr {
+ let Spellings = [];
+ let Args = [UnsignedIntArgument<"Alignment">];
+}
+
+def MSP430Interrupt : Attr {
+ let Spellings = [];
+ let Args = [UnsignedIntArgument<"Number">];
+}
+
+def NoDebug : Attr {
+ let Spellings = ["nodebug"];
+}
+
+def NoInline : Attr {
+ let Spellings = ["noinline"];
+}
+
+def NonNull : Attr {
+ let Spellings = ["nonnull"];
+ let Args = [VariadicArgument<UnsignedIntArgument<"Args">>];
+}
+
+def NoReturn : Attr {
+ let Spellings = ["noreturn"];
+ // FIXME: Does GCC allow this on the function instead?
+ let Subjects = [Function];
+ let Namespaces = ["", "std"];
+}
+
+def NoInstrumentFunction : Attr {
+ let Spellings = ["no_instrument_function"];
+ let Subjects = [Function];
+}
+
+def NoThrow : Attr {
+ let Spellings = ["nothrow"];
+}
+
+def NSReturnsRetained : Attr {
+ let Spellings = ["ns_returns_retained"];
+}
+
+def NSReturnsNotRetained : Attr {
+ let Spellings = ["ns_returns_not_retained"];
+}
+
+def ObjCException : Attr {
+ let Spellings = ["objc_exception"];
+}
+
+def ObjCNSObject : Attr {
+ let Spellings = ["NSOjbect"];
+}
+
+def Override : Attr {
+ let Spellings = ["override"];
+ let Subjects = [CXXVirtualMethod];
+ let Namespaces = ["", "std"];
+ let DoNotEmit = 0;
+}
+
+def Overloadable : Attr {
+ let Spellings = ["overloadable"];
+}
+
+def Packed : Attr {
+ let Spellings = ["packed"];
+}
+
+def Pure : Attr {
+ let Spellings = ["pure"];
+}
+
+def Regparm : Attr {
+ let Spellings = ["regparm"];
+ let Args = [UnsignedIntArgument<"NumParams">];
+}
+
+def ReqdWorkGroupSize : Attr {
+ let Spellings = ["reqd_work_group_size"];
+ let Args = [UnsignedIntArgument<"XDim">, UnsignedIntArgument<"YDim">,
+ UnsignedIntArgument<"ZDim">];
+}
+
+def InitPriority : Attr {
+ let Spellings = ["init_priority"];
+ let Args = [UnsignedIntArgument<"Priority">];
+}
+
+def Section : Attr {
+ let Spellings = ["section"];
+ let Args = [StringArgument<"Name">];
+}
+
+def Sentinel : Attr {
+ let Spellings = ["sentinel"];
+ let Args = [DefaultIntArgument<"NulPos", 0>,
+ DefaultIntArgument<"Sentinel", 0>];
+}
+
+def StdCall : Attr {
+ let Spellings = ["stdcall", "__stdcall"];
+}
+
+def ThisCall : Attr {
+ let Spellings = ["thiscall", "__thiscall"];
+}
+
+def TransparentUnion : Attr {
+ let Spellings = ["transparent_union"];
+}
+
+def Unavailable : Attr {
+ let Spellings = ["unavailable"];
+}
+
+def Unused : Attr {
+ let Spellings = ["unused"];
+}
+
+def Used : Attr {
+ let Spellings = ["used"];
+}
+
+def Visibility : Attr {
+ let Spellings = ["visibility"];
+ let Args = [StringArgument<"Visibility">];
+}
+
+def WarnUnusedResult : Attr {
+ let Spellings = ["warn_unused_result"];
+}
+
+def Weak : Attr {
+ let Spellings = ["weak"];
+}
+
+def WeakImport : Attr {
+ let Spellings = ["weak_import"];
+}
+
+def WeakRef : Attr {
+ let Spellings = ["weakref"];
+}
+
+def X86ForceAlignArgPointer : Attr {
+ let Spellings = [];
+}
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
new file mode 100644
index 000000000000..822573b734a7
--- /dev/null
+++ b/include/clang/Basic/AttrKinds.h
@@ -0,0 +1,31 @@
+//===----- Attr.h - Enum values for C Attribute Kinds ----------*- 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 attr::Kind enum
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ATTRKINDS_H
+#define LLVM_CLANG_ATTRKINDS_H
+
+namespace clang {
+
+namespace attr {
+
+// Kind - This is a list of all the recognized kinds of attributes.
+enum Kind {
+#define ATTR(X) X,
+#include "clang/Basic/AttrList.inc"
+ NUM_ATTRS
+};
+
+} // end namespace attr
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index b306954975f4..cad28243a31c 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -540,6 +540,7 @@ LIBBUILTIN(siglongjmp, "vSJi", "fr", "setjmp.h")
// id objc_msgSend(id, SEL)
// but we need new type letters for that.
LIBBUILTIN(objc_msgSend, "v*.", "f", "objc/message.h")
+BUILTIN(__builtin_objc_memmove_collectable, "v*v*vC*z", "nF")
// Builtin math library functions
LIBBUILTIN(pow, "ddd", "fe", "math.h")
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 4973076ae24d..54e4c2b2083a 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -14,7 +14,13 @@
// The format of this database matches clang/Basic/Builtins.def.
-// FIXME: This is just a placeholder. NEON intrinsics should be listed here.
+// In libgcc
+BUILTIN(__clear_cache, "vc*c*", "")
BUILTIN(__builtin_thread_pointer, "v*", "")
+// NEON
+#define GET_NEON_BUILTINS
+#include "clang/Basic/arm_neon.inc"
+#undef GET_NEON_BUILTINS
+
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
index 287bba96df25..e0518dcdb681 100644
--- a/include/clang/Basic/BuiltinsPPC.def
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -18,14 +18,6 @@
// The format of this database matches clang/Basic/Builtins.def.
// This is just a placeholder, the types and attributes are wrong.
-BUILTIN(__builtin_altivec_abs_v16qi, "V16UcV16Sc", "")
-BUILTIN(__builtin_altivec_abs_v8hi, "V8UsV8Ss", "")
-BUILTIN(__builtin_altivec_abs_v4si, "V4UiV4Si", "")
-
-BUILTIN(__builtin_altivec_abss_v16qi, "V16UcV16Sc", "")
-BUILTIN(__builtin_altivec_abss_v8hi, "V8UsV8Ss", "")
-BUILTIN(__builtin_altivec_abss_v4si, "V4UiV4Si", "")
-
BUILTIN(__builtin_altivec_vaddcuw, "V4UiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vaddsbs, "V16ScV16ScV16Sc", "")
@@ -49,6 +41,67 @@ BUILTIN(__builtin_altivec_vavguh, "V8UsV8UsV8Us", "")
BUILTIN(__builtin_altivec_vavgsw, "V4SiV4SiV4Si", "")
BUILTIN(__builtin_altivec_vavguw, "V4UiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vrfip, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcfsx, "V4fV4ii", "")
+BUILTIN(__builtin_altivec_vcfux, "V4fV4ii", "")
+BUILTIN(__builtin_altivec_vctsxs, "V4SiV4fi", "")
+BUILTIN(__builtin_altivec_vctuxs, "V4UiV4fi", "")
+
+BUILTIN(__builtin_altivec_dss, "vUi", "")
+BUILTIN(__builtin_altivec_dssall, "v", "")
+BUILTIN(__builtin_altivec_dst, "vv*iUi", "")
+BUILTIN(__builtin_altivec_dstt, "vv*iUi", "")
+BUILTIN(__builtin_altivec_dstst, "vv*iUi", "")
+BUILTIN(__builtin_altivec_dststt, "vv*iUi", "")
+
+BUILTIN(__builtin_altivec_vexptefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vrfim, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_lvx, "V4iiv*", "")
+BUILTIN(__builtin_altivec_lvxl, "V4iiv*", "")
+BUILTIN(__builtin_altivec_lvebx, "V16civ*", "")
+BUILTIN(__builtin_altivec_lvehx, "V8siv*", "")
+BUILTIN(__builtin_altivec_lvewx, "V4iiv*", "")
+
+BUILTIN(__builtin_altivec_vlogefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_lvsl, "V16cUcv*", "")
+BUILTIN(__builtin_altivec_lvsr, "V16cUcv*", "")
+
+BUILTIN(__builtin_altivec_vmaddfp, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_altivec_vmhaddshs, "V8sV8sV8sV8s", "")
+BUILTIN(__builtin_altivec_vmhraddshs, "V8sV8sV8sV8s", "")
+
+BUILTIN(__builtin_altivec_vmsumubm, "V4UiV16UcV16UcV4Ui", "")
+BUILTIN(__builtin_altivec_vmsummbm, "V4SiV16ScV16UcV4Si", "")
+BUILTIN(__builtin_altivec_vmsumuhm, "V4UiV8UsV8UsV4Ui", "")
+BUILTIN(__builtin_altivec_vmsumshm, "V4SiV8SsV8SsV4Si", "")
+BUILTIN(__builtin_altivec_vmsumuhs, "V4UiV8UsV8UsV4Ui", "")
+BUILTIN(__builtin_altivec_vmsumshs, "V4SiV8SsV8SsV4Si", "")
+
+BUILTIN(__builtin_altivec_vmuleub, "V8UsV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vmulesb, "V8SsV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vmuleuh, "V4UiV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vmulesh, "V4SiV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vmuloub, "V8UsV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vmulosb, "V8SsV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vmulouh, "V4UiV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vmulosh, "V4SiV8SsV8Ss", "")
+
+BUILTIN(__builtin_altivec_vnmsubfp, "V4fV4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vpkpx, "V8sV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vpkuhus, "V16UcV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vpkshss, "V16ScV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vpkuwus, "V8UsV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vpkswss, "V8SsV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vpkshus, "V16UcV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vpkswus, "V8UsV4SiV4Si", "")
+
+BUILTIN(__builtin_altivec_vperm_4si, "V4iV4iV4iV16Uc", "")
+
BUILTIN(__builtin_altivec_stvx, "vV4iiv*", "")
BUILTIN(__builtin_altivec_stvxl, "vV4iiv*", "")
BUILTIN(__builtin_altivec_stvebx, "vV16civ*", "")
@@ -92,6 +145,48 @@ BUILTIN(__builtin_altivec_vminfp, "V4fV4fV4f", "")
BUILTIN(__builtin_altivec_mtvscr, "vV4i", "")
+BUILTIN(__builtin_altivec_vrefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vrlb, "V16cV16cV16Uc", "")
+BUILTIN(__builtin_altivec_vrlh, "V8sV8sV8Us", "")
+BUILTIN(__builtin_altivec_vrlw, "V4iV4iV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsel_4si, "V4iV4iV4iV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsl, "V4iV4iV4i", "")
+BUILTIN(__builtin_altivec_vslo, "V4iV4iV4i", "")
+
+BUILTIN(__builtin_altivec_vsrab, "V16cV16cV16Uc", "")
+BUILTIN(__builtin_altivec_vsrah, "V8sV8sV8Us", "")
+BUILTIN(__builtin_altivec_vsraw, "V4iV4iV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsr, "V4iV4iV4i", "")
+BUILTIN(__builtin_altivec_vsro, "V4iV4iV4i", "")
+
+BUILTIN(__builtin_altivec_vrfin, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vrsqrtefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vsubcuw, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsum4sbs, "V4SiV16ScV4Si", "")
+BUILTIN(__builtin_altivec_vsum4ubs, "V4UiV16UcV4Ui", "")
+BUILTIN(__builtin_altivec_vsum4shs, "V4SiV8SsV4Si", "")
+
+BUILTIN(__builtin_altivec_vsum2sws, "V4SiV4SiV4Si", "")
+
+BUILTIN(__builtin_altivec_vsumsws, "V4SiV4SiV4Si", "")
+
+BUILTIN(__builtin_altivec_vrfiz, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vupkhsb, "V8sV16c", "")
+BUILTIN(__builtin_altivec_vupkhpx, "V4UiV8s", "")
+BUILTIN(__builtin_altivec_vupkhsh, "V4iV8s", "")
+
+BUILTIN(__builtin_altivec_vupklsb, "V8sV16c", "")
+BUILTIN(__builtin_altivec_vupklpx, "V4UiV8s", "")
+BUILTIN(__builtin_altivec_vupklsh, "V4iV8s", "")
+
BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "")
BUILTIN(__builtin_altivec_vcmpgefp_p, "iiV4fV4f", "")
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
index c2a4e1364a9e..c5952365d593 100644
--- a/include/clang/Basic/CMakeLists.txt
+++ b/include/clang/Basic/CMakeLists.txt
@@ -18,3 +18,15 @@ tablegen(DiagnosticGroups.inc
-gen-clang-diag-groups)
add_custom_target(ClangDiagnosticGroups
DEPENDS DiagnosticGroups.inc)
+
+set(LLVM_TARGET_DEFINITIONS Attr.td)
+tablegen(AttrList.inc
+ -gen-clang-attr-list
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrList
+ DEPENDS AttrList.inc)
+
+# ARM NEON
+set(LLVM_TARGET_DEFINITIONS arm_neon.td)
+tablegen(arm_neon.inc -gen-arm-neon-sema)
+add_custom_target(ClangARMNeon DEPENDS arm_neon.inc)
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
new file mode 100644
index 000000000000..203fb451e38b
--- /dev/null
+++ b/include/clang/Basic/DeclNodes.td
@@ -0,0 +1,70 @@
+class AttrSubject;
+
+class Decl<bit abstract = 0> : AttrSubject {
+ bit Abstract = abstract;
+}
+
+class DDecl<Decl base, bit abstract = 0> : Decl<abstract> {
+ Decl Base = base;
+}
+
+class DeclContext { }
+
+def TranslationUnit : Decl, DeclContext;
+def Named : Decl<1>;
+ def Namespace : DDecl<Named>, DeclContext;
+ def UsingDirective : DDecl<Named>;
+ def NamespaceAlias : DDecl<Named>;
+ def Type : DDecl<Named, 1>;
+ def Typedef : DDecl<Type>;
+ def UnresolvedUsingTypename : DDecl<Type>;
+ def Tag : DDecl<Type, 1>, DeclContext;
+ def Enum : DDecl<Tag>;
+ def Record : DDecl<Tag>;
+ def CXXRecord : DDecl<Record>;
+ def ClassTemplateSpecialization : DDecl<CXXRecord>;
+ def ClassTemplatePartialSpecialization
+ : DDecl<ClassTemplateSpecialization>;
+ def TemplateTypeParm : DDecl<Type>;
+ def Value : DDecl<Named, 1>;
+ def EnumConstant : DDecl<Value>;
+ def UnresolvedUsingValue : DDecl<Value>;
+ def Declarator : DDecl<Value, 1>;
+ def Function : DDecl<Declarator>, DeclContext;
+ def CXXMethod : DDecl<Function>;
+ def CXXConstructor : DDecl<CXXMethod>;
+ def CXXDestructor : DDecl<CXXMethod>;
+ def CXXConversion : DDecl<CXXMethod>;
+ def Field : DDecl<Declarator>;
+ def ObjCIvar : DDecl<Field>;
+ def ObjCAtDefsField : DDecl<Field>;
+ def Var : DDecl<Declarator>;
+ def ImplicitParam : DDecl<Var>;
+ def ParmVar : DDecl<Var>;
+ def NonTypeTemplateParm : DDecl<Var>;
+ def Template : DDecl<Named, 1>;
+ def FunctionTemplate : DDecl<Template>;
+ def ClassTemplate : DDecl<Template>;
+ def TemplateTemplateParm : DDecl<Template>;
+ def Using : DDecl<Named>;
+ def UsingShadow : DDecl<Named>;
+ def ObjCMethod : DDecl<Named>, DeclContext;
+ def ObjCContainer : DDecl<Named, 1>, DeclContext;
+ def ObjCCategory : DDecl<ObjCContainer>;
+ def ObjCProtocol : DDecl<ObjCContainer>;
+ def ObjCInterface : DDecl<ObjCContainer>;
+ def ObjCImpl : DDecl<ObjCContainer, 1>;
+ def ObjCCategoryImpl : DDecl<ObjCImpl>;
+ def ObjCImplementation : DDecl<ObjCImpl>;
+ def ObjCProperty : DDecl<Named>;
+ def ObjCCompatibleAlias : DDecl<Named>;
+def LinkageSpec : Decl, DeclContext;
+def ObjCPropertyImpl : Decl;
+def ObjCForwardProtocol : Decl;
+def ObjCClass : Decl;
+def FileScopeAsm : Decl;
+def AccessSpec : Decl;
+def Friend : Decl;
+def FriendTemplate : Decl;
+def StaticAssert : Decl;
+def Block : Decl, DeclContext;
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 62f06edb7785..1fe0d8154cd4 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -24,7 +24,6 @@
namespace llvm {
template <typename T> class SmallVectorImpl;
- class raw_ostream;
}
namespace clang {
@@ -36,8 +35,6 @@ namespace clang {
class LangOptions;
class PartialDiagnostic;
class Preprocessor;
- class SourceManager;
- class SourceRange;
// Import the diagnostic enums themselves.
namespace diag {
@@ -98,8 +95,8 @@ namespace clang {
/// compilation.
class FixItHint {
public:
- /// \brief Tokens that should be removed to correct the error.
- SourceRange RemoveRange;
+ /// \brief Code that should be removed to correct the error.
+ CharSourceRange RemoveRange;
/// \brief The location at which we should insert code to correct
/// the error.
@@ -129,15 +126,18 @@ public:
/// \brief Create a code modification hint that removes the given
/// source range.
- static FixItHint CreateRemoval(SourceRange RemoveRange) {
+ static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
FixItHint Hint;
Hint.RemoveRange = RemoveRange;
return Hint;
}
-
+ static FixItHint CreateRemoval(SourceRange RemoveRange) {
+ return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
+ }
+
/// \brief Create a code modification hint that replaces the given
/// source range with the given code string.
- static FixItHint CreateReplacement(SourceRange RemoveRange,
+ static FixItHint CreateReplacement(CharSourceRange RemoveRange,
llvm::StringRef Code) {
FixItHint Hint;
Hint.RemoveRange = RemoveRange;
@@ -145,6 +145,11 @@ public:
Hint.CodeToInsert = Code;
return Hint;
}
+
+ static FixItHint CreateReplacement(SourceRange RemoveRange,
+ llvm::StringRef Code) {
+ return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
+ }
};
/// Diagnostic - This concrete class is used by the front-end to report
@@ -176,7 +181,14 @@ public:
ak_nestednamespec, // NestedNameSpecifier *
ak_declcontext // DeclContext *
};
-
+
+ /// Specifies which overload candidates to display when overload resolution
+ /// fails.
+ enum OverloadsShown {
+ Ovl_All, ///< Show all overloads.
+ Ovl_Best ///< Show just the "best" overload candidates.
+ };
+
/// ArgumentValue - This typedef represents on argument value, which is a
/// union discriminated by ArgumentKind, with a value.
typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
@@ -188,6 +200,7 @@ private:
bool ErrorsAsFatal; // Treat errors like fatal errors.
bool SuppressSystemWarnings; // Suppress warnings in system headers.
bool SuppressAllDiagnostics; // Suppress all diagnostics.
+ OverloadsShown ShowOverloads; // Which overload candidates to show.
unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit.
unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
// 0 -> no limit.
@@ -318,6 +331,13 @@ public:
}
bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
+ /// \brief Specify which overload candidates to show when overload resolution
+ /// fails. By default, we show all candidates.
+ void setShowOverloads(OverloadsShown Val) {
+ ShowOverloads = Val;
+ }
+ OverloadsShown getShowOverloads() const { return ShowOverloads; }
+
/// \brief Pretend that the last diagnostic issued was ignored. This can
/// be used by clients who suppress diagnostics themselves.
void setLastDiagnosticIgnored() {
@@ -582,7 +602,7 @@ private:
/// DiagRanges - The list of ranges added to this diagnostic. It currently
/// only support 10 ranges, could easily be extended if needed.
- SourceRange DiagRanges[10];
+ CharSourceRange DiagRanges[10];
enum { MaxFixItHints = 3 };
@@ -681,7 +701,7 @@ public:
}
}
- void AddSourceRange(const SourceRange &R) const {
+ void AddSourceRange(const CharSourceRange &R) const {
assert(NumRanges <
sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
"Too many arguments to diagnostic!");
@@ -752,11 +772,17 @@ operator<<(const DiagnosticBuilder &DB, T *DC) {
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const SourceRange &R) {
- DB.AddSourceRange(R);
+ DB.AddSourceRange(CharSourceRange::getTokenRange(R));
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const CharSourceRange &R) {
+ DB.AddSourceRange(R);
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const FixItHint &Hint) {
DB.AddFixItHint(Hint);
return DB;
@@ -849,7 +875,7 @@ public:
return DiagObj->NumDiagRanges;
}
- SourceRange getRange(unsigned Idx) const {
+ const CharSourceRange &getRange(unsigned Idx) const {
assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
return DiagObj->DiagRanges[Idx];
}
@@ -886,7 +912,7 @@ class StoredDiagnostic {
Diagnostic::Level Level;
FullSourceLoc Loc;
std::string Message;
- std::vector<SourceRange> Ranges;
+ std::vector<CharSourceRange> Ranges;
std::vector<FixItHint> FixIts;
public:
@@ -902,7 +928,7 @@ public:
const FullSourceLoc &getLocation() const { return Loc; }
llvm::StringRef getMessage() const { return Message; }
- typedef std::vector<SourceRange>::const_iterator range_iterator;
+ typedef std::vector<CharSourceRange>::const_iterator range_iterator;
range_iterator range_begin() const { return Ranges.begin(); }
range_iterator range_end() const { return Ranges.end(); }
unsigned range_size() const { return Ranges.size(); }
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 88e7dc19aec5..4b0bf57bef63 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -66,6 +66,7 @@ def err_target_unknown_triple : Error<
"unknown target triple '%0', please use -triple or -arch">;
def err_target_unknown_cpu : Error<"unknown target CPU '%0'">;
def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
+def err_target_unknown_cxxabi : Error<"unknown C++ ABI '%0'">;
def err_target_invalid_feature : Error<"invalid target feature '%0'">;
// Source manager
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index c7cad7395c0b..989ec38d2950 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -18,7 +18,10 @@ def err_fe_invalid_ast_action : Error<"invalid action for AST input">,
DefaultFatal;
// Error generated by the backend.
def err_fe_inline_asm : Error<"%0">, CatInlineAsm;
-def note_fe_inline_asm_here : Note<"generated from here">;
+def note_fe_inline_asm_here : Note<"instantated into assembly here">;
+
+
+
def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
@@ -186,9 +189,6 @@ def warn_pch_math_errno : Error<
"math functions %select{do not respect|respect}0 'errno' in PCH "
"file but they are currently set to %select{not respect|respect}1 "
"'errno'">;
-def warn_pch_overflow_checking : Error<
- "signed integer overflow checking was %select{disabled|enabled}0 in PCH "
- "file but is currently %select{disabled|enabled}1">;
def warn_pch_optimize : Error<
"the macro '__OPTIMIZE__' was %select{not defined|defined}0 in "
"the PCH file but is currently %select{undefined|defined}1">;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index b79bf8e2edbe..930fe422cff0 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -17,11 +17,14 @@ def Implicit : DiagGroup<"implicit", [
]>;
// Empty DiagGroups are recognized by clang but ignored.
+def : DiagGroup<"abi">;
def : DiagGroup<"address">;
def AddressOfTemporary : DiagGroup<"address-of-temporary">;
def : DiagGroup<"aggregate-return">;
+def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
def : DiagGroup<"attributes">;
def : DiagGroup<"bad-function-cast">;
+def BoolConversions : DiagGroup<"bool-conversions">;
def : DiagGroup<"c++-compat">;
def : DiagGroup<"cast-align">;
def : DiagGroup<"cast-qual">;
@@ -51,6 +54,7 @@ def : DiagGroup<"inline">;
def : DiagGroup<"int-to-pointer-cast">;
def : DiagGroup<"invalid-pch">;
def LiteralRange : DiagGroup<"literal-range">;
+def : DiagGroup<"main">;
def MissingBraces : DiagGroup<"missing-braces">;
def : DiagGroup<"missing-declarations">;
def : DiagGroup<"missing-format-attribute">;
@@ -62,6 +66,7 @@ def : DiagGroup<"newline-eof">;
def LongLong : DiagGroup<"long-long">;
def MismatchedTags : DiagGroup<"mismatched-tags">;
def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
+def InitializerOverrides : DiagGroup<"initializer-overrides">;
def NonNull : DiagGroup<"nonnull">;
def : DiagGroup<"nonportable-cfstrings">;
def : DiagGroup<"non-virtual-dtor">;
@@ -70,13 +75,17 @@ def : DiagGroup<"overflow">;
def : DiagGroup<"overloaded-virtual">;
def : DiagGroup<"packed">;
def PointerArith : DiagGroup<"pointer-arith">;
+def PoundWarning : DiagGroup<"#warnings">,
+ DiagCategory<"#warning Directive">;
def : DiagGroup<"pointer-to-int-cast">;
def : DiagGroup<"redundant-decls">;
def ReturnType : DiagGroup<"return-type">;
+def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy">;
def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
def : DiagGroup<"sequence-point">;
def Shadow : DiagGroup<"shadow">;
def : DiagGroup<"shorten-64-to-32">;
+def : DiagGroup<"sign-promo">;
def SignCompare : DiagGroup<"sign-compare">;
def : DiagGroup<"synth">;
@@ -108,6 +117,7 @@ def Trigraphs : DiagGroup<"trigraphs">;
def : DiagGroup<"type-limits">;
def Uninitialized : DiagGroup<"uninitialized">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
+def UnknownAttributes : DiagGroup<"unknown-attributes">;
def UnusedArgument : DiagGroup<"unused-argument">;
def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
def UnusedFunction : DiagGroup<"unused-function">;
@@ -137,7 +147,7 @@ def Parentheses : DiagGroup<"parentheses", [DiagGroup<"idiomatic-parentheses">]>
// -Wconversion has its own warnings, but we split this one out for
// legacy reasons.
def Conversion : DiagGroup<"conversion",
- [DiagGroup<"shorten-64-to-32">]>,
+ [DiagGroup<"shorten-64-to-32">, BoolConversions]>,
DiagCategory<"Value Conversion Issue">;
def Unused : DiagGroup<"unused",
@@ -157,6 +167,7 @@ def Format2 : DiagGroup<"format=2",
def Extra : DiagGroup<"extra", [
MissingFieldInitializers,
+ InitializerOverrides,
SemiBeforeMethodBody,
SignCompare,
UnusedParameter
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 848e85c8ba41..21c93e7e8fa2 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -106,7 +106,7 @@ def err_invalid_pth_file : Error<
//===----------------------------------------------------------------------===//
// Preprocessor Diagnostics
//===----------------------------------------------------------------------===//
-def pp_hash_warning : Warning<"#warning%0">, InGroup<DiagGroup<"#warnings">>;
+def pp_hash_warning : Warning<"#warning%0">, InGroup<PoundWarning>;
def pp_include_next_in_primary : Warning<
"#include_next in primary source file">;
def pp_include_macros_out_of_predefines : Error<
@@ -225,6 +225,9 @@ def err__Pragma_malformed : Error<
"_Pragma takes a parenthesized string literal">;
def err_pragma_comment_malformed : Error<
"pragma comment requires parenthesized identifier and optional string">;
+def err_pragma_message_malformed : Error<
+ "pragma message requires parenthesized string">;
+def warn_pragma_message : Warning<"%0">;
def warn_pragma_ignored : Warning<"unknown pragma ignored">,
InGroup<UnknownPragmas>, DefaultIgnore;
def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 934bd0db1e01..ca761f9bf5e9 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -24,7 +24,9 @@ def ext_empty_source_file : Extension<"ISO C forbids an empty source file">;
def ext_top_level_semi : Extension<
"extra ';' outside of a function">;
def ext_extra_struct_semi : Extension<
- "extra ';' inside a struct or union">;
+ "extra ';' inside a %0">;
+def ext_extra_ivar_semi : Extension<
+ "extra ';' inside instance variable list">;
def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">;
def ext_plain_complex : ExtWarn<
@@ -35,6 +37,7 @@ def ext_thread_before : Extension<"'__thread' before 'static'">;
def ext_empty_struct_union_enum : Extension<"use of empty %0 extension">;
+def error_empty_enum : Error<"use of empty enum">;
def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">;
def err_invalid_short_spec : Error<"'short %0' is invalid">;
def err_invalid_long_spec : Error<"'long %0' is invalid">;
@@ -103,7 +106,7 @@ def err_expected_fn_body : Error<
"expected function body after function declarator">;
def err_expected_method_body : Error<"expected method body">;
def err_invalid_token_after_toplevel_declarator : Error<
- "invalid token after top level declarator">;
+ "expected ';' after top level declarator">;
def err_expected_statement : Error<"expected statement">;
def err_expected_lparen_after : Error<"expected '(' after '%0'">;
def err_expected_lparen_after_id : Error<"expected '(' after %0">;
@@ -168,11 +171,15 @@ def err_typename_invalid_functionspec : Error<
def err_invalid_decl_spec_combination : Error<
"cannot combine with previous '%0' declaration specifier">;
def err_invalid_vector_decl_spec_combination : Error<
- "cannot combine with previous '%0' declaration specifier. '__vector' must be first">;
+ "cannot combine with previous '%0' declaration specifier. "
+ "'__vector' must be first">;
def err_invalid_pixel_decl_spec_combination : Error<
- "'__pixel' must be preceded by '__vector'. '%0' declaration specifier not allowed here">;
-def err_invalid_vector_double_decl_spec_combination : Error<
- "cannot use 'double' with '__vector'">;
+ "'__pixel' must be preceded by '__vector'. "
+ "'%0' declaration specifier not allowed here">;
+def err_invalid_vector_decl_spec : Error<
+ "cannot use '%0' with '__vector'">;
+def err_invalid_vector_bool_decl_spec : Error<
+ "cannot use '%0' with '__vector bool'">;
def warn_vector_long_decl_spec_combination : Warning<
"Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
def err_friend_invalid_in_context : Error<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 0ba31aee2ff5..8fac1edecfa8 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -21,12 +21,6 @@ def ext_expr_not_ice : Extension<
"expression is not integer constant expression "
"(but is allowed as an extension)">;
-def ext_null_pointer_expr_not_ice : Extension<
- "null pointer expression is not an integer constant expression "
- "(but is allowed as an extension)">;
-
-
-
// Semantic analysis of constant literals.
def ext_predef_outside_function : Warning<
"predefined identifier is only valid inside function">;
@@ -80,9 +74,10 @@ def err_designator_for_scalar_init : Error<
"designator in initializer for scalar type %0">;
def warn_subobject_initializer_overrides : Warning<
"subobject initialization overrides initialization of other fields "
- "within its enclosing subobject">;
+ "within its enclosing subobject">, InGroup<InitializerOverrides>;
def warn_initializer_overrides : Warning<
- "initializer overrides prior initialization of this subobject">;
+ "initializer overrides prior initialization of this subobject">,
+ InGroup<InitializerOverrides>;
def note_previous_initializer : Note<
"previous initialization %select{|with side effects }0is here"
"%select{| (side effects may not occur at run time)}0">;
@@ -125,6 +120,8 @@ def warn_use_out_of_scope_declaration : Warning<
"use of out-of-scope declaration of %0">;
def err_inline_non_function : Error<
"'inline' can only appear on functions">;
+def warn_qual_return_type : Warning<
+ "'%0' type qualifier%s1 on return type %plural{1:has|:have}1 no effect">;
def warn_decl_shadow :
Warning<"declaration shadows a %select{"
@@ -230,6 +227,7 @@ def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "
/// parser diagnostics
def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">;
+def err_typedef_not_identifier : Error<"typedef name must be an identifier">;
def err_statically_allocated_object : Error<
"interface type cannot be statically allocated">;
def err_object_cannot_be_passed_returned_by_value : Error<
@@ -458,6 +456,9 @@ def warn_weak_vtable : Warning<
"emitted in every translation unit">,
InGroup<DiagGroup<"weak-vtables">>, DefaultIgnore;
+def ext_using_undefined_std : ExtWarn<
+ "using directive refers to implicitly-defined namespace 'std'">;
+
// C++ exception specifications
def err_exception_spec_in_typedef : Error<
"exception specifications are not allowed in typedefs">;
@@ -486,6 +487,10 @@ def err_access : Error<
"%1 is a %select{private|protected}0 member of %3">, NoSFINAE;
def err_access_ctor : Error<
"calling a %select{private|protected}0 constructor of class %2">, NoSFINAE;
+def ext_rvalue_to_reference_access_ctor : ExtWarn<
+ "C++98 requires an accessible copy constructor for class %2 when binding "
+ "a reference to a temporary; was %select{private|protected}0">,
+ NoSFINAE, InGroup<BindToTemporaryCopy>;
def err_access_base : Error<
"%select{base class|inherited virtual base class}0 %1 has %select{private|"
"protected}3 %select{constructor|copy constructor|copy assignment operator|"
@@ -507,6 +512,9 @@ def err_access_dtor_vbase :
def err_access_dtor_temp :
Error<"temporary of type %0 has %select{private|protected}1 destructor">,
NoSFINAE;
+def err_access_dtor_exception :
+ Error<"exception object of type %0 has %select{private|protected}1 "
+ "destructor">, NoSFINAE;
def err_access_dtor_field :
Error<"field of type %1 has %select{private|protected}2 destructor">,
NoSFINAE;
@@ -549,6 +557,9 @@ def err_dependent_nested_name_spec : Error<
"parameter">;
def err_nested_name_member_ref_lookup_ambiguous : Error<
"lookup of %0 in member access expression is ambiguous">;
+def ext_nested_name_member_ref_lookup_ambiguous : ExtWarn<
+ "lookup of %0 in member access expression is ambiguous; using member of %1">,
+ InGroup<AmbigMemberTemplate>;
def note_ambig_member_ref_object_type : Note<
"lookup in the object type %0 refers here">;
def note_ambig_member_ref_scope : Note<
@@ -744,6 +755,13 @@ def err_temp_copy_no_viable : Error<
"returning object|throwing object|copying member subobject|copying array "
"element|allocating object|copying temporary|initializing base subobject|"
"initializing vector element}0 of type %1">;
+def ext_rvalue_to_reference_temp_copy_no_viable : ExtWarn<
+ "no viable constructor %select{copying variable|copying parameter|"
+ "returning object|throwing object|copying member subobject|copying array "
+ "element|allocating object|copying temporary|initializing base subobject|"
+ "initializing vector element}0 of type %1; C++98 requires a copy "
+ "constructor when binding a reference to a temporary">,
+ InGroup<BindToTemporaryCopy>;
def err_temp_copy_ambiguous : Error<
"ambiguous constructor call when %select{copying variable|copying "
"parameter|returning object|throwing object|copying member subobject|copying "
@@ -797,9 +815,15 @@ def err_attribute_wrong_number_arguments : Error<
"attribute requires %0 argument(s)">;
def err_attribute_missing_parameter_name : Error<
"attribute requires unquoted parameter">;
-def err_attribute_invalid_vector_type : Error<"invalid vector type %0">;
+def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
def err_attribute_argument_not_int : Error<
"'%0' attribute requires integer constant">;
+def err_attribute_argument_outof_range : Error<
+ "init_priority attribute requires integer constant between "
+ "101 and 65535 inclusive">;
+def err_init_priority_object_attr : Error<
+ "can only use ‘init_priority’ attribute on file-scope definitions "
+ "of objects of class type">;
def err_attribute_argument_n_not_int : Error<
"'%0' attribute requires parameter %1 to be an integer constant">;
def err_attribute_argument_n_not_string : Error<
@@ -838,7 +862,8 @@ def err_attribute_address_space_too_high : Error<
def err_attribute_address_multiple_qualifiers : Error<
"multiple address spaces specified for type">;
def err_implicit_pointer_address_space_cast : Error<
- "illegal implicit cast between two pointers with different address spaces">;
+ "illegal implicit conversion between two pointers with different address "
+ "spaces">;
def err_as_qualified_auto_decl : Error<
"automatic variable qualified with an address space">;
def err_arg_with_address_space : Error<
@@ -854,6 +879,8 @@ def err_attribute_aligned_not_power_of_two : Error<
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
"'%0' redeclared without %1 attribute: previous %1 ignored">;
def warn_attribute_ignored : Warning<"%0 attribute ignored">;
+def warn_unknown_attribute_ignored : Warning<
+ "unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
def warn_attribute_precede_definition : Warning<
"attribute declaration must precede definition">;
def warn_attribute_void_function_method : Warning<
@@ -899,30 +926,34 @@ def err_cconv_knr : Error<
"function with no prototype cannot use %0 calling convention">;
def err_cconv_varargs : Error<
"variadic function cannot use %0 calling convention">;
+def err_regparm_mismatch : Error<"function declared with with regparm(%0) "
+ "attribute was previously declared %plural{0:without the regparm|1:"
+ "with the regparm(1)|2:with the regparm(2)|3:with the regparm(3)|:with the"
+ "regparm}1 attribute">;
def warn_impcast_vector_scalar : Warning<
- "implicit cast turns vector to scalar: %0 to %1">,
+ "implicit conversion turns vector to scalar: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_complex_scalar : Warning<
- "implicit cast discards imaginary component: %0 to %1">,
+ "implicit conversion discards imaginary component: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_float_precision : Warning<
- "implicit cast loses floating-point precision: %0 to %1">,
+ "implicit conversion loses floating-point precision: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_float_integer : Warning<
- "implicit cast turns floating-point number into integer: %0 to %1">,
+ "implicit conversion turns floating-point number into integer: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_sign : Warning<
- "implicit cast changes signedness: %0 to %1">,
+ "implicit conversion changes signedness: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_sign_conditional : Warning<
"operand of ? changes signedness: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_precision : Warning<
- "implicit cast loses integer precision: %0 to %1">,
+ "implicit conversion loses integer precision: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_64_32 : Warning<
- "implicit cast loses integer precision: %0 to %1">,
+ "implicit conversion loses integer precision: %0 to %1">,
InGroup<DiagGroup<"shorten-64-to-32">>, DefaultIgnore;
def warn_attribute_ignored_for_field_of_type : Warning<
@@ -937,8 +968,8 @@ def warn_transparent_union_attribute_not_definition : Warning<
"transparent_union attribute can only be applied to a union definition; "
"attribute ignored">;
def warn_transparent_union_attribute_floating : Warning<
- "first field of a transparent union cannot have floating point or vector "
- "type; transparent_union attribute ignored">;
+ "first field of a transparent union cannot have %select{floating point|"
+ "vector}0 type %1; transparent_union attribute ignored">;
def warn_transparent_union_attribute_zero_fields : Warning<
"transparent union definition must contain at least one field; "
"transparent_union attribute ignored">;
@@ -1077,6 +1108,9 @@ 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 note_ovl_too_many_candidates : Note<
+ "remaining %0 candidate%s0 omitted; "
+ "pass -fshow-overloads=all to show them">;
def note_ovl_candidate : Note<"candidate "
"%select{function|function|constructor|"
"function |function |constructor |"
@@ -1084,6 +1118,10 @@ def note_ovl_candidate : Note<"candidate "
"is the implicit copy constructor|"
"is the implicit copy assignment operator}0%1">;
+def warn_init_pointer_from_false : Warning<
+ "initialization of pointer of type %0 from literal 'false'">,
+ InGroup<BoolConversions>;
+
def note_ovl_candidate_bad_deduction : Note<
"candidate template ignored: failed template argument deduction">;
def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored: "
@@ -1168,6 +1206,17 @@ def note_ovl_candidate_bad_cvr : Note<"candidate "
"%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_ovl_candidate_bad_base_to_derived_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: cannot %select{convert from|convert from|bind}2 "
+ "%select{base class pointer|superclass|base class object of type}2 %3 to "
+ "%select{derived class pointer|subclass|derived class reference}2 %4 for "
+ "%ordinal5 argument">;
+
def note_ambiguous_type_conversion: Note<
"because of ambiguity in conversion of %0 to %1">;
def note_ovl_builtin_binary_candidate : Note<
@@ -1234,6 +1283,7 @@ def err_template_param_different_kind : Error<
"%select{|template parameter }0redeclaration">;
def note_template_param_different_kind : Note<
"template parameter has a different kind in template argument">;
+
def err_template_nontype_parm_different_type : Error<
"template non-type parameter has a different type %0 in template "
"%select{|template parameter }1redeclaration">;
@@ -1528,6 +1578,8 @@ def err_explicit_instantiation_nontemplate_type : Error<
"explicit instantiation of non-templated type %0">;
def note_nontemplate_decl_here : Note<
"non-templated declaration is here">;
+def err_explicit_instantiation_in_class : Error<
+ "explicit instantiation of %0 in class scope">;
def err_explicit_instantiation_out_of_scope : Error<
"explicit instantiation of %0 not in a namespace enclosing %1">;
def err_explicit_instantiation_must_be_global : Error<
@@ -1560,10 +1612,9 @@ def note_explicit_instantiation_candidate : Note<
"explicit instantiation candidate function template here %0">;
def err_explicit_instantiation_inline : Error<
"explicit instantiation cannot be 'inline'">;
-def err_explicit_instantiation_without_qualified_id : Error<
- "qualifier in explicit instantiation of %q0 requires a template-id">;
-def err_explicit_instantiation_without_qualified_id_quals : Error<
- "qualifier in explicit instantiation of '%0%1' requires a template-id">;
+def ext_explicit_instantiation_without_qualified_id : ExtWarn<
+ "qualifier in explicit instantiation of %q0 requires a template-id "
+ "(a typedef is not permitted)">;
def err_explicit_instantiation_unqualified_wrong_namespace : Error<
"explicit instantiation of %q0 must occur in %1">;
def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning<
@@ -1588,6 +1639,8 @@ def note_typename_refers_here : Note<
"referenced member %0 is declared here">;
def err_typename_missing : Error<
"missing 'typename' prior to dependent type name '%0%1'">;
+def ext_typename_outside_of_template : ExtWarn<
+ "'typename' occurs outside of a template">;
def err_template_kw_refers_to_non_template : Error<
"%0 following the 'template' keyword does not refer to a template">;
@@ -1599,6 +1652,8 @@ 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'">;
+def ext_template_outside_of_template : ExtWarn<
+ "'template' keyword outside of a template">;
// C++0x Variadic Templates
def err_template_param_pack_default_arg : Error<
@@ -1606,6 +1661,18 @@ def err_template_param_pack_default_arg : Error<
def err_template_param_pack_must_be_last_template_parameter : Error<
"template parameter pack must be the last template parameter">;
+def err_template_parameter_pack_non_pack : Error<
+ "template %select{type|non-type|template}0 parameter%select{| pack}1 "
+ "conflicts with previous template %select{type|non-type|template}0 "
+ "parameter%select{ pack|}1">;
+def note_template_parameter_pack_non_pack : Note<
+ "template %select{type|non-type|template}0 parameter%select{| pack}1 "
+ "does not match template %select{type|non-type|template}0 "
+ "parameter%select{ pack|}1 in template argument">;
+def note_template_parameter_pack_here : Note<
+ "previous template %select{type|non-type|template}0 "
+ "parameter%select{| pack}1 declared here">;
+
def err_unexpected_typedef : Error<
"unexpected type name %0: expected expression">;
def err_unexpected_namespace : Error<
@@ -1674,6 +1741,9 @@ def ext_forward_ref_enum : Extension<
"ISO C forbids forward references to 'enum' types">;
def err_forward_ref_enum : Error<
"ISO C++ forbids forward references to 'enum' types">;
+def ext_forward_ref_enum_def : Extension<
+ "redeclaration of already-defined enum %0 is a GNU extension">, InGroup<GNU>;
+
def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
def err_duplicate_member : Error<"duplicate member %0">;
def err_misplaced_ivar : Error<
@@ -1848,6 +1918,8 @@ def err_illegal_decl_array_of_functions : Error<
"'%0' declared as array of functions of type %1">;
def err_illegal_decl_array_incomplete_type : Error<
"array has incomplete element type %0">;
+def err_illegal_message_expr_incomplete_type : Error<
+ "objective-c message has incomplete result type %0">;
def err_illegal_decl_array_of_references : Error<
"'%0' declared as array of references of type %1">;
def err_array_star_outside_prototype : Error<
@@ -2028,6 +2100,11 @@ def err_typecheck_unary_expr : Error<
"invalid argument type %0 to unary expression">;
def err_typecheck_indirection_requires_pointer : Error<
"indirection requires pointer operand (%0 invalid)">;
+def warn_indirection_through_null : Warning<
+ "indirection of non-volatile null pointer will be deleted, not trap">;
+def note_indirection_through_null : Note<
+ "consider using __builtin_trap() or qualifying pointer with 'volatile'">;
+
def err_indirection_requires_nonfragile_object : Error<
"indirection cannot be to an interface in non-fragile ABI (%0 invalid)">;
def err_direct_interface_unsupported : Error<
@@ -2046,8 +2123,12 @@ def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
"ordered comparison of function pointers (%0 and %1)">;
def ext_typecheck_comparison_of_fptr_to_void : Extension<
"equality comparison between function pointer and void pointer (%0 and %1)">;
+def err_typecheck_comparison_of_fptr_to_void : Error<
+ "equality comparison between function pointer and void pointer (%0 and %1)">;
def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
"comparison between pointer and integer (%0 and %1)">;
+def err_typecheck_comparison_of_pointer_integer : Error<
+ "comparison between pointer and integer (%0 and %1)">;
def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
"comparison of distinct pointer types (%0 and %1)">;
def ext_typecheck_cond_incompatible_operands : ExtWarn<
@@ -2081,9 +2162,11 @@ def err_invalid_member_use_in_static_method : Error<
"invalid use of member %0 in static member function">;
def err_invalid_qualified_function_type : Error<
"type qualifier is not allowed on this function">;
+def err_invalid_qualified_function_pointer : Error<
+ "type qualifier is not allowed on this function %select{pointer|reference}0">;
def err_invalid_qualified_typedef_function_type_use : Error<
- "a qualified function type cannot be used to declare a nonmember function "
- "or a static member function">;
+ "a qualified function type cannot be used to declare a "
+ "%select{static member|nonmember}0 function">;
def err_invalid_non_static_member_use : Error<
"invalid use of nonstatic data member %0">;
@@ -2260,13 +2343,26 @@ def err_new_array_nonconst : Error<
"only the first dimension of an allocated array may have dynamic size">;
def err_new_array_init_args : Error<
"array 'new' cannot have initialization arguments">;
-def err_new_paren_array_nonconst : Error<
+def ext_new_paren_array_nonconst : ExtWarn<
"when type is in parentheses, array cannot have dynamic size">;
def err_placement_new_non_placement_delete : Error<
"'new' expression with placement arguments refers to non-placement "
"'operator delete'">;
def err_array_size_not_integral : Error<
"array size expression must have integral or enumerated type, not %0">;
+def err_array_size_incomplete_type : Error<
+ "array size expression has incomplete class type %0">;
+def err_array_size_explicit_conversion : Error<
+ "array size expression of type %0 requires explicit conversion to type %1">;
+def note_array_size_conversion : Note<
+ "conversion to %select{integral|enumeration}0 type %1 declared here">;
+def err_array_size_ambiguous_conversion : Error<
+ "ambiguous conversion of array size expression of type %0 to an integral or "
+ "enumeration type">;
+def ext_array_size_conversion : Extension<
+ "implicit conversion from array size expression of type %0 to "
+ "%select{integral|enumeration}1 type %2 is a C++0x extension">;
+
def err_default_init_const : Error<
"default initialization of an object of const type %0"
"%select{| requires a user-provided default constructor}1">;
@@ -2866,11 +2962,17 @@ def warn_printf_asterisk_missing_arg : Warning<
def warn_printf_asterisk_wrong_type : Warning<
"field %select{width|precision}0 should have type %1, but argument has type %2">,
InGroup<Format>;
-def warn_printf_nonsensical_precision: Warning<
- "precision used in '%0' conversion specifier (where it has no meaning)">,
+def warn_printf_nonsensical_optional_amount: Warning<
+ "%select{field width|precision}0 used with '%1' conversion specifier, resulting in undefined behavior">,
InGroup<Format>;
def warn_printf_nonsensical_flag: Warning<
- "flag '%0' results in undefined behavior in '%1' conversion specifier">,
+ "flag '%0' results in undefined behavior with '%1' conversion specifier">,
+ InGroup<Format>;
+def warn_printf_nonsensical_length: Warning<
+ "length modifier '%0' results in undefined behavior or no effect with '%1' conversion specifier">,
+ InGroup<Format>;
+def warn_printf_ignored_flag: Warning<
+ "flag '%0' is ignored when flag '%1' is present">,
InGroup<Format>;
// CHECK: returning address/reference of stack memory
@@ -2886,8 +2988,10 @@ def err_ret_local_block : Error<
// For non-floating point, expressions of the form x == x or x != x
// should result in a warning, since these always evaluate to a constant.
-def warn_selfcomparison : Warning<
- "self-comparison always results in a constant value">;
+// Array comparisons have similar warnings
+def warn_comparison_always : Warning<
+ "%select{self-|array }0comparison always evaluates to %select{false|true|a constant}1">;
+
def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
"unspecified (use strncmp instead)">;
@@ -2956,13 +3060,13 @@ def err_first_argument_to_va_arg_not_of_type_va_list : Error<
"first argument to 'va_arg' is of type %0 and not 'va_list'">;
def warn_return_missing_expr : Warning<
- "non-void %select{function|method}1 %0 should return a value">,
+ "non-void %select{function|method}1 %0 should return a value">, DefaultError,
InGroup<ReturnType>;
def ext_return_missing_expr : ExtWarn<
- "non-void %select{function|method}1 %0 should return a value">,
+ "non-void %select{function|method}1 %0 should return a value">, DefaultError,
InGroup<ReturnType>;
def ext_return_has_expr : ExtWarn<
- "void %select{function|method}1 %0 should not return a value">,
+ "void %select{function|method}1 %0 should not return a value">, DefaultError,
InGroup<ReturnType>;
def ext_return_has_void_expr : Extension<
"void %select{function|method}1 %0 should not return void expression">;
@@ -2993,6 +3097,8 @@ def err_vector_incorrect_num_initializers : Error<
"%select{too many|too few}0 elements in vector initialization (expected %1 elements, have %2)">;
def err_altivec_empty_initializer : Error<"expected initializer">;
+def err_invalid_neon_type_code : Error<
+ "incompatible constant for this __builtin_neon function">;
def err_argument_invalid_range : Error<
"argument should be a value from %0 to %1">;
@@ -3003,7 +3109,9 @@ def err_constant_integer_arg_type : Error<
"argument to %0 must be a constant integer">;
def ext_mixed_decls_code : Extension<
- "ISO C90 forbids mixing declarations and code">;
+ "ISO C90 forbids mixing declarations and code">,
+ InGroup<DiagGroup<"declaration-after-statement">>;
+
def err_non_variable_decl_in_for : Error<
"declaration of non-local variable in 'for' loop">;
def err_toomany_element_decls : Error<
@@ -3094,6 +3202,11 @@ 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">;
+def err_using_directive_suggest : Error<
+ "no namespace named %0; did you mean %1?">;
+def err_using_directive_member_suggest : Error<
+ "no namespace named %0 in %1; did you mean %2?">;
+def note_namespace_defined_here : Note<"namespace %0 defined here">;
} // end of sema category
} // end of sema component.
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 582d59c18a37..6b8bcdc52f6f 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -89,7 +89,8 @@ public:
// The 'this' pointer really points to a
// std::pair<IdentifierInfo, const char*>, where internal pointer
// points to the external string data.
- return ((std::pair<IdentifierInfo, const char*>*) this)->second;
+ typedef std::pair<IdentifierInfo, const char*> actualtype;
+ return ((const actualtype*) this)->second;
}
/// getLength - Efficiently return the length of this identifier info.
@@ -101,7 +102,8 @@ public:
// The 'this' pointer really points to a
// std::pair<IdentifierInfo, const char*>, where internal pointer
// points to the external string data.
- const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second-2;
+ typedef std::pair<IdentifierInfo, const char*> actualtype;
+ const char* p = ((const actualtype*) this)->second - 2;
return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
}
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 1ed86f190af3..bbcceb70ac91 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -66,9 +66,6 @@ public:
unsigned MathErrno : 1; // Math functions must respect errno
// (modulo the platform support).
- unsigned OverflowChecking : 1; // Extension to call a handler function when
- // signed integer arithmetic overflows.
-
unsigned HeinousExtensions : 1; // Extensions that we really don't like and
// may be ripped out at any time.
@@ -102,20 +99,21 @@ public:
unsigned DumpRecordLayouts : 1; /// Dump the layout of IRgen'd records.
unsigned DumpVTableLayouts : 1; /// Dump the layouts of emitted vtables.
unsigned NoConstantCFStrings : 1; // Do not do CF strings
+ unsigned InlineVisibilityHidden : 1; // Whether inline C++ methods have
+ // hidden visibility by default.
+ unsigned SpellChecking : 1; // Whether to perform spell-checking for error
+ // recovery.
// FIXME: This is just a temporary option, for testing purposes.
unsigned NoBitFieldTypeAlign : 1;
private:
- unsigned GC : 2; // Objective-C Garbage Collection modes. We
- // declare this enum as unsigned because MSVC
- // insists on making enums signed. Set/Query
- // this value using accessors.
+ // We declare multibit enums as unsigned because MSVC insists on making enums
+ // signed. Set/Query these values using accessors.
+ unsigned GC : 2; // Objective-C Garbage Collection modes.
unsigned SymbolVisibility : 3; // Symbol's visibility.
- unsigned StackProtector : 2; // Whether stack protectors are on. We declare
- // this enum as unsigned because MSVC insists
- // on making enums signed. Set/Query this
- // value using accessors.
+ unsigned StackProtector : 2; // Whether stack protectors are on.
+ unsigned SignedOverflowBehavior : 2; // How to handle signed integer overflow.
public:
unsigned InstantiationDepth; // Maximum template instantiation depth.
@@ -129,13 +127,19 @@ public:
Protected,
Hidden
};
+
+ enum SignedOverflowBehaviorTy {
+ SOB_Undefined, // Default C standard behavior.
+ SOB_Defined, // -fwrapv
+ SOB_Trapping // -ftrapv
+ };
LangOptions() {
Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
GNUMode = GNUKeywords = ImplicitInt = Digraphs = 0;
HexFloats = 0;
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
- NoConstantCFStrings = 0;
+ NoConstantCFStrings = 0; InlineVisibilityHidden = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;
Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0;
@@ -146,20 +150,19 @@ public:
AltiVec = OpenCL = StackProtector = 0;
SymbolVisibility = (unsigned) Default;
-
+
ThreadsafeStatics = 1;
POSIXThreads = 0;
Blocks = 0;
EmitAllDecls = 0;
MathErrno = 1;
-
+ SignedOverflowBehavior = SOB_Undefined;
+
AssumeSaneOperatorNew = 1;
-
- // FIXME: The default should be 1.
- AccessControl = 0;
+ AccessControl = 1;
ElideConstructors = 1;
- OverflowChecking = 0;
+ SignedOverflowBehavior = 0;
ObjCGCBitmapPrint = 0;
InstantiationDepth = 1024;
@@ -178,6 +181,7 @@ public:
CatchUndefined = 0;
DumpRecordLayouts = 0;
DumpVTableLayouts = 0;
+ SpellChecking = 1;
NoBitFieldTypeAlign = 0;
}
@@ -195,6 +199,13 @@ public:
return (VisibilityMode) SymbolVisibility;
}
void setVisibilityMode(VisibilityMode v) { SymbolVisibility = (unsigned) v; }
+
+ SignedOverflowBehaviorTy getSignedOverflowBehavior() const {
+ return (SignedOverflowBehaviorTy)SignedOverflowBehavior;
+ }
+ void setSignedOverflowBehavior(SignedOverflowBehaviorTy V) {
+ SignedOverflowBehavior = (unsigned)V;
+ }
};
} // end namespace clang
diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile
index 48f7f9d8cc7b..7db3e2982af4 100644
--- a/include/clang/Basic/Makefile
+++ b/include/clang/Basic/Makefile
@@ -1,16 +1,33 @@
-LEVEL = ../../../../..
-BUILT_SOURCES = DiagnosticAnalysisKinds.inc DiagnosticASTKinds.inc \
+CLANG_LEVEL := ../../..
+BUILT_SOURCES = \
+ DiagnosticAnalysisKinds.inc DiagnosticASTKinds.inc \
DiagnosticCommonKinds.inc DiagnosticDriverKinds.inc \
DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \
DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \
- DiagnosticGroups.inc
+ DiagnosticGroups.inc AttrList.inc arm_neon.inc \
+ Version.inc
TABLEGEN_INC_FILES_COMMON = 1
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td)
+# Compute the Clang version from the LLVM version, unless specified explicitly.
+ifndef CLANG_VERSION
+CLANG_VERSION := $(subst svn,,$(LLVMVersion))
+endif
+
+CLANG_VERSION_COMPONENTS := $(subst ., ,$(CLANG_VERSION))
+CLANG_VERSION_MAJOR := $(word 1,$(CLANG_VERSION_COMPONENTS))
+CLANG_VERSION_MINOR := $(word 2,$(CLANG_VERSION_COMPONENTS))
+CLANG_VERSION_PATCHLEVEL := $(word 3,$(CLANG_VERSION_COMPONENTS))
+ifeq ($(CLANG_VERSION_PATCHLEVEL),)
+CLANG_HAS_VERSION_PATCHLEVEL := 0
+else
+CLANG_HAS_VERSION_PATCHLEVEL := 1
+endif
+
$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen"
$(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $<
@@ -19,4 +36,20 @@ $(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_T
$(Echo) "Building Clang diagnostic groups with tblgen"
$(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $<
+$(ObjDir)/AttrList.inc.tmp : Attr.td $(TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang attribute list with tblgen"
+ $(Verb) $(TableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../.. $<
+
+$(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang arm_neon.inc with tblgen"
+ $(Verb) $(TableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) $<
+$(ObjDir)/Version.inc.tmp : Version.inc.in Makefile $(LLVM_OBJ_ROOT)/Makefile.config $(ObjDir)/.dir
+ $(Echo) "Updating Clang version info."
+ $(Verb)sed -e "s#@CLANG_VERSION@#$(CLANG_VERSION)#g" \
+ -e "s#@CLANG_VERSION_MAJOR@#$(CLANG_VERSION_MAJOR)#g" \
+ -e "s#@CLANG_VERSION_MINOR@#$(CLANG_VERSION_MINOR)#g" \
+ -e "s#@CLANG_VERSION_PATCHLEVEL@#$(CLANG_VERSION_PATCHLEVEL)#g" \
+ -e "s#@CLANG_HAS_VERSION_PATCHLEVEL@#$(CLANG_HAS_VERSION_PATCHLEVEL)#g" \
+ $< > $@
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index 89fae87ae8ef..cd0da97e2ba3 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -59,7 +59,7 @@ public:
/// DiagRanges - The list of ranges added to this diagnostic. It currently
/// only support 10 ranges, could easily be extended if needed.
- SourceRange DiagRanges[10];
+ CharSourceRange DiagRanges[10];
enum { MaxFixItHints = 3 };
@@ -142,7 +142,7 @@ private:
DiagStorage = 0;
}
- void AddSourceRange(const SourceRange &R) const {
+ void AddSourceRange(const CharSourceRange &R) const {
if (!DiagStorage)
DiagStorage = getStorage();
@@ -264,10 +264,16 @@ public:
friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
const SourceRange &R) {
- PD.AddSourceRange(R);
+ PD.AddSourceRange(CharSourceRange::getTokenRange(R));
return PD;
}
+ friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const CharSourceRange &R) {
+ PD.AddSourceRange(R);
+ return PD;
+ }
+
friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
const FixItHint &Hint) {
PD.AddFixItHint(Hint);
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 0bbeffefc725..35f27fbebd72 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -172,6 +172,56 @@ public:
return B != X.B || E != X.E;
}
};
+
+/// CharSourceRange - This class represents a character granular source range.
+/// The underlying SourceRange can either specify the starting/ending character
+/// of the range, or it can specify the start or the range and the start of the
+/// last token of the range (a "token range"). In the token range case, the
+/// size of the last token must be measured to determine the actual end of the
+/// range.
+class CharSourceRange {
+ SourceRange Range;
+ bool IsTokenRange;
+public:
+ CharSourceRange() : IsTokenRange(false) {}
+ CharSourceRange(SourceRange R, bool ITR) : Range(R),IsTokenRange(ITR){}
+
+ static CharSourceRange getTokenRange(SourceRange R) {
+ CharSourceRange Result;
+ Result.Range = R;
+ Result.IsTokenRange = true;
+ return Result;
+ }
+
+ static CharSourceRange getCharRange(SourceRange R) {
+ CharSourceRange Result;
+ Result.Range = R;
+ Result.IsTokenRange = false;
+ return Result;
+ }
+
+ static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) {
+ return getTokenRange(SourceRange(B, E));
+ }
+ static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) {
+ return getCharRange(SourceRange(B, E));
+ }
+
+ /// isTokenRange - Return true if the end of this range specifies the start of
+ /// the last token. Return false if the end of this range specifies the last
+ /// character in the range.
+ bool isTokenRange() const { return IsTokenRange; }
+
+ SourceLocation getBegin() const { return Range.getBegin(); }
+ SourceLocation getEnd() const { return Range.getEnd(); }
+ const SourceRange &getAsRange() const { return Range; }
+
+ void setBegin(SourceLocation b) { Range.setBegin(b); }
+ void setEnd(SourceLocation e) { Range.setEnd(e); }
+
+ bool isValid() const { return Range.isValid(); }
+ bool isInvalid() const { return !isValid(); }
+};
/// FullSourceLoc - A SourceLocation and its associated SourceManager. Useful
/// for argument passing to functions that expect both objects.
diff --git a/include/clang/AST/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 60c94a609b4a..a2f69730a010 100644
--- a/include/clang/AST/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -1,4 +1,6 @@
-class Stmt<bit abstract = 0> {
+class AttrSubject;
+
+class Stmt<bit abstract = 0> : AttrSubject {
bit Abstract = abstract;
}
@@ -93,11 +95,10 @@ def CXXNullPtrLiteralExpr : DStmt<Expr>;
def CXXThisExpr : DStmt<Expr>;
def CXXThrowExpr : DStmt<Expr>;
def CXXDefaultArgExpr : DStmt<Expr>;
-def CXXZeroInitValueExpr : DStmt<Expr>;
+def CXXScalarValueInitExpr : DStmt<Expr>;
def CXXNewExpr : DStmt<Expr>;
def CXXDeleteExpr : DStmt<Expr>;
def CXXPseudoDestructorExpr : DStmt<Expr>;
-def UnresolvedLookupExpr : DStmt<Expr>;
def UnaryTypeTraitExpr : DStmt<Expr>;
def DependentScopeDeclRefExpr : DStmt<Expr>;
def CXXConstructExpr : DStmt<Expr>;
@@ -107,7 +108,9 @@ def CXXExprWithTemporaries : DStmt<Expr>;
def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
def CXXUnresolvedConstructExpr : DStmt<Expr>;
def CXXDependentScopeMemberExpr : DStmt<Expr>;
-def UnresolvedMemberExpr : DStmt<Expr>;
+def OverloadExpr : DStmt<Expr, 1>;
+def UnresolvedLookupExpr : DStmt<OverloadExpr>;
+def UnresolvedMemberExpr : DStmt<OverloadExpr>;
// Obj-C Expressions.
def ObjCStringLiteral : DStmt<Expr>;
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 00fd9b92e13e..5763a12135e9 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -51,12 +51,14 @@ protected:
unsigned char FloatWidth, FloatAlign;
unsigned char DoubleWidth, DoubleAlign;
unsigned char LongDoubleWidth, LongDoubleAlign;
+ unsigned char LargeArrayMinWidth, LargeArrayAlign;
unsigned char LongWidth, LongAlign;
unsigned char LongLongWidth, LongLongAlign;
const char *DescriptionString;
const char *UserLabelPrefix;
const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
unsigned char RegParmMax, SSERegParmMax;
+ std::string CXXABI;
unsigned HasAlignMac68kSupport : 1;
@@ -194,6 +196,11 @@ public:
return *LongDoubleFormat;
}
+ // getLargeArrayMinWidth/Align - Return the minimum array size that is
+ // 'large' and its alignment.
+ unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
+ unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
+
/// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
/// target, in bits.
unsigned getIntMaxTWidth() const {
@@ -390,6 +397,11 @@ public:
return "";
}
+ /// getCXXABI - Get the C++ ABI in use.
+ virtual llvm::StringRef getCXXABI() const {
+ return CXXABI;
+ }
+
/// setCPU - Target the specific CPU.
///
/// \return - False on error (invalid CPU name).
@@ -406,6 +418,16 @@ public:
return false;
}
+ /// setCXXABI - Use this specific C++ ABI.
+ ///
+ /// \return - False on error (invalid ABI name).
+ virtual bool setCXXABI(const std::string &Name) {
+ if (Name != "itanium" && Name != "microsoft")
+ return false;
+ CXXABI = Name;
+ return true;
+ }
+
/// setFeatureEnabled - Enable or disable a specific target feature,
/// the feature name must be valid.
///
@@ -450,7 +472,12 @@ public:
return -1;
}
-
+ /// getStaticInitSectionSpecifier - Return the section to use for C++ static
+ /// initialization functions.
+ virtual const char *getStaticInitSectionSpecifier() const {
+ return 0;
+ }
+
protected:
virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
return PointerWidth;
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index eeaab1558fd1..19b0cbbf5820 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -19,6 +19,10 @@ namespace clang {
class TargetOptions {
public:
+ TargetOptions() {
+ CXXABI = "itanium";
+ }
+
/// If given, the name of the target triple to compile for. If not given the
/// target will be selected to match the host.
std::string Triple;
@@ -29,6 +33,10 @@ public:
/// If given, the name of the target ABI to use.
std::string ABI;
+ /// If given, the name of the target C++ ABI to use. If not given, defaults
+ /// to "itanium".
+ std::string CXXABI;
+
/// The list of target specific features to enable or disable -- this should
/// be a list of strings starting with by '+' or '-'.
std::vector<std::string> Features;
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index b3b61841a8c3..9948677662cd 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -17,15 +17,7 @@
#include "llvm/ADT/StringRef.h"
-/// \brief Clang major version
-#define CLANG_VERSION_MAJOR 2
-
-// FIXME: Updates to this file must also update CMakeLists.txt and VER.
-/// \brief Clang minor version
-#define CLANG_VERSION_MINOR 0
-
-/// \brief Clang patchlevel version
-// #define CLANG_VERSION_PATCHLEVEL 1
+#include "clang/Basic/Version.inc"
/// \brief Helper macro for CLANG_VERSION_STRING.
#define CLANG_MAKE_VERSION_STRING2(X) #X
diff --git a/include/clang/Basic/Version.inc.in b/include/clang/Basic/Version.inc.in
new file mode 100644
index 000000000000..ccf8430c8ba2
--- /dev/null
+++ b/include/clang/Basic/Version.inc.in
@@ -0,0 +1,6 @@
+#define CLANG_VERSION @CLANG_VERSION@
+#define CLANG_VERSION_MAJOR @CLANG_VERSION_MAJOR@
+#define CLANG_VERSION_MINOR @CLANG_VERSION_MINOR@
+#if @CLANG_HAS_VERSION_PATCHLEVEL@
+#define CLANG_VERSION_PATCHLEVEL @CLANG_VERSION_PATCHLEVEL@
+#endif
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
new file mode 100644
index 000000000000..b42755ca72ae
--- /dev/null
+++ b/include/clang/Basic/arm_neon.td
@@ -0,0 +1,341 @@
+//===--- arm_neon.td - ARM NEON compiler interface ------------------------===//
+//
+// 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 TableGen definitions from which the ARM NEON header
+// file will be generated. See ARM document DUI0348B.
+//
+//===----------------------------------------------------------------------===//
+
+class Op;
+
+def OP_NONE : Op;
+def OP_ADD : Op;
+def OP_SUB : Op;
+def OP_MUL : Op;
+def OP_MLA : Op;
+def OP_MLS : Op;
+def OP_MUL_N : Op;
+def OP_MLA_N : Op;
+def OP_MLS_N : Op;
+def OP_EQ : Op;
+def OP_GE : Op;
+def OP_LE : Op;
+def OP_GT : Op;
+def OP_LT : Op;
+def OP_NEG : Op;
+def OP_NOT : Op;
+def OP_AND : Op;
+def OP_OR : Op;
+def OP_XOR : Op;
+def OP_ANDN : Op;
+def OP_ORN : Op;
+def OP_CAST : Op;
+def OP_HI : Op;
+def OP_LO : Op;
+def OP_CONC : Op;
+def OP_DUP : Op;
+def OP_SEL : Op;
+def OP_REV64 : Op;
+def OP_REV32 : Op;
+def OP_REV16 : Op;
+
+class Inst <string p, string t, Op o> {
+ string Prototype = p;
+ string Types = t;
+ Op Operand = o;
+ bit isShift = 0;
+}
+
+// Used to generate Builtins.def
+class SInst<string p, string t> : Inst<p, t, OP_NONE> {}
+class IInst<string p, string t> : Inst<p, t, OP_NONE> {}
+class WInst<string p, string t> : Inst<p, t, OP_NONE> {}
+
+// prototype: return (arg, arg, ...)
+// v: void
+// t: best-fit integer (int/poly args)
+// x: signed integer (int/float args)
+// u: unsigned integer (int/float args)
+// f: float (int args)
+// d: default
+// w: double width elements, same num elts
+// n: double width elements, half num elts
+// h: half width elements, double num elts
+// e: half width elements, double num elts, unsigned
+// i: constant int
+// l: constant uint64
+// s: scalar of element type
+// a: scalar of element type (splat to vector type)
+// k: default elt width, double num elts
+// #: array of default vectors
+// p: pointer type
+// c: const pointer type
+
+// sizes:
+// c: char
+// s: short
+// i: int
+// l: long
+// f: float
+// h: half-float
+
+// size modifiers:
+// U: unsigned
+// Q: 128b
+// P: polynomial
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.1 Addition
+def VADD : Inst<"ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_ADD>;
+def VADDL : SInst<"wdd", "csiUcUsUi">;
+def VADDW : SInst<"wwd", "csiUcUsUi">;
+def VHADD : SInst<"ddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VRHADD : SInst<"ddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VQADD : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VADDHN : IInst<"dww", "csiUcUsUi">;
+def VRADDHN : IInst<"dww", "csiUcUsUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.2 Multiplication
+def VMUL : Inst<"ddd", "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPc", OP_MUL>;
+def VMLA : Inst<"dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLA>;
+def VMLAL : SInst<"wwdd", "csiUcUsUi">;
+def VMLS : Inst<"dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLS>;
+def VMLSL : SInst<"wwdd", "csiUcUsUi">;
+def VQDMULH : SInst<"ddd", "siQsQi">;
+def VQRDMULH : SInst<"ddd", "siQsQi">;
+def VQDMLAL : SInst<"wwdd", "si">;
+def VQDMLSL : SInst<"wwdd", "si">;
+def VMULL : SInst<"wdd", "csiUcUsUiPc">;
+def VQDMULL : SInst<"wdd", "si">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.3 Subtraction
+def VSUB : Inst<"ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_SUB>;
+def VSUBL : SInst<"wdd", "csiUcUsUi">;
+def VSUBW : SInst<"wwd", "csiUcUsUi">;
+def VQSUB : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VHSUB : SInst<"ddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VSUBHN : IInst<"dww", "csiUcUsUi">;
+def VRSUBHN : IInst<"dww", "csiUcUsUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.4 Comparison
+def VCEQ : Inst<"udd", "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPc", OP_EQ>;
+def VCGE : Inst<"udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GE>;
+def VCLE : Inst<"udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LE>;
+def VCGT : Inst<"udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GT>;
+def VCLT : Inst<"udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LT>;
+def VCAGE : IInst<"udd", "fQf">;
+def VCALE : IInst<"udd", "fQf">;
+def VCAGT : IInst<"udd", "fQf">;
+def VCALT : IInst<"udd", "fQf">;
+def VTST : WInst<"udd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.5 Absolute Difference
+def VABD : SInst<"ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
+def VABDL : SInst<"wdd", "csiUcUsUi">;
+def VABA : SInst<"dddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VABAL : SInst<"wwdd", "csiUcUsUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.6 Max/Min
+def VMAX : SInst<"ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
+def VMIN : SInst<"ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.7 Pairdise Addition
+def VPADD : IInst<"ddd", "csiUcUsUif">;
+def VPADDL : SInst<"nd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VPADAL : SInst<"nnd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.8-9 Folding Max/Min
+def VPMAX : SInst<"ddd", "csiUcUsUif">;
+def VPMIN : SInst<"ddd", "csiUcUsUif">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.10 Reciprocal/Sqrt
+def VRECPS : IInst<"ddd", "fQf">;
+def VRSQRTS : IInst<"ddd", "fQf">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.11 Shifts by signed variable
+def VSHL : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VQSHL : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VRSHL : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VQRSHL : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.12 Shifts by constant
+let isShift = 1 in {
+def VSHR_N : SInst<"ddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VSHL_N : IInst<"ddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VRSHR_N : SInst<"ddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VSRA_N : SInst<"dddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VRSRA_N : SInst<"dddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VQSHL_N : SInst<"ddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VQSHLU_N : SInst<"udi", "csilQcQsQiQl">;
+def VSHRN_N : IInst<"hki", "silUsUiUl">;
+def VQSHRUN_N : SInst<"eki", "sil">;
+def VQRSHRUN_N : SInst<"eki", "sil">;
+def VQSHRN_N : SInst<"hki", "silUsUiUl">;
+def VRSHRN_N : IInst<"hki", "silUsUiUl">;
+def VQRSHRN_N : SInst<"hki", "silUsUiUl">;
+def VSHLL_N : SInst<"wdi", "csiUcUsUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.13 Shifts with insert
+def VSRI_N : WInst<"dddi", "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs">;
+def VSLI_N : WInst<"dddi", "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs">;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.14 Loads and stores of a single vector
+def VLD1 : WInst<"dc", "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD1_LANE : WInst<"dcdi", "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD1_DUP : WInst<"dc", "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST1 : WInst<"vpd", "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST1_LANE : WInst<"vpdi", "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.15 Loads and stores of an N-element structure
+def VLD2 : WInst<"2c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD3 : WInst<"3c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD4 : WInst<"4c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD2_DUP : WInst<"2c", "UcUsUiUlcsilhfPcPs">;
+def VLD3_DUP : WInst<"3c", "UcUsUiUlcsilhfPcPs">;
+def VLD4_DUP : WInst<"4c", "UcUsUiUlcsilhfPcPs">;
+def VLD2_LANE : WInst<"2c2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VLD3_LANE : WInst<"3c3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VLD4_LANE : WInst<"4c4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VST2 : WInst<"vp2", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST3 : WInst<"vp3", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST4 : WInst<"vp4", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST2_LANE : WInst<"vp2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VST3_LANE : WInst<"vp3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VST4_LANE : WInst<"vp4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.16 Extract lanes from a vector
+def VGET_LANE : IInst<"sdi", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.17 Set lanes within a vector
+def VSET_LANE : IInst<"dsdi", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.18 Initialize a vector from bit pattern
+def VCREATE: Inst<"dl", "csihfUcUsUiUlPcPsl", OP_CAST>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.19 Set all lanes to same value
+def VDUP_N : Inst<"ds", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
+def VMOV_N : Inst<"ds", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.20 Combining vectors
+def VCOMBINE : Inst<"kdd", "csilhfUcUsUiUlPcPs", OP_CONC>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.21 Splitting vectors
+def VGET_HIGH : Inst<"dk", "csilhfUcUsUiUlPcPs", OP_HI>;
+def VGET_LOW : Inst<"dk", "csilhfUcUsUiUlPcPs", OP_LO>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.22 Converting vectors
+def VCVT_S32 : SInst<"xd", "fQf">;
+def VCVT_U32 : SInst<"ud", "fQf">;
+def VCVT_F16 : SInst<"hk", "f">;
+def VCVT_N_S32 : SInst<"xdi", "fQf">;
+def VCVT_N_U32 : SInst<"udi", "fQf">;
+def VCVT_F32 : SInst<"fd", "iUiQiQUi">;
+def VCVT_F32_F16 : SInst<"kh", "f">;
+def VCVT_N_F32 : SInst<"fdi", "iUiQiQUi">;
+def VMOVN : IInst<"hk", "silUsUiUl">;
+def VMOVL : SInst<"wd", "csiUcUsUi">;
+def VQMOVN : SInst<"hk", "silUsUiUl">;
+def VQMOVUN : SInst<"ek", "sil">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.23-24 Table lookup, Extended table lookup
+def VTBL1 : WInst<"ddt", "UccPc">;
+def VTBL2 : WInst<"d2t", "UccPc">;
+def VTBL3 : WInst<"d3t", "UccPc">;
+def VTBL4 : WInst<"d4t", "UccPc">;
+def VTBX1 : WInst<"dddt", "UccPc">;
+def VTBX2 : WInst<"dd2t", "UccPc">;
+def VTBX3 : WInst<"dd3t", "UccPc">;
+def VTBX4 : WInst<"dd4t", "UccPc">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.25 Operations with a scalar value
+def VMLA_LANE : IInst<"ddddi", "siUsUifQsQiQUsQUiQf">;
+def VMLAL_LANE : SInst<"wwddi", "siUsUi">;
+def VQDMLAL_LANE : SInst<"wwddi", "si">;
+def VMLS_LANE : IInst<"ddddi", "siUsUifQsQiQUsQUiQf">;
+def VMLSL_LANE : SInst<"wwddi", "siUsUi">;
+def VQDMLSL_LANE : SInst<"wwddi", "si">;
+def VMUL_N : Inst<"dds", "sifUsUiQsQiQfQUsQUi", OP_MUL_N>;
+def VMULL_N : SInst<"wda", "siUsUi">;
+def VMULL_LANE : SInst<"wddi", "siUsUi">;
+def VQDMULL_N : SInst<"wda", "si">;
+def VQDMULL_LANE : SInst<"wddi", "si">;
+def VQDMULH_N : SInst<"dda", "siQsQi">;
+def VQDMULH_LANE : SInst<"dddi", "siQsQi">;
+def VQRDMULH_N : SInst<"dda", "siQsQi">;
+def VQRDMULH_LANE : SInst<"dddi", "siQsQi">;
+def VMLA_N : Inst<"ddda", "siUsUifQsQiQUsQUiQf", OP_MLA_N>;
+def VMLAL_N : SInst<"wwda", "siUsUi">;
+def VQDMLAL_N : SInst<"wwda", "si">;
+def VMLS_N : Inst<"ddds", "siUsUifQsQiQUsQUiQf", OP_MLS_N>;
+def VMLSL_N : SInst<"wwda", "siUsUi">;
+def VQDMLSL_N : SInst<"wwda", "si">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.26 Vector Extract
+def VEXT : WInst<"dddi", "cUcPcsUsPsiUilUlQcQUcQPcQsQUsQPsQiQUiQlQUl">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.27 Reverse vector elements (sdap endianness)
+def VREV64 : Inst<"dd", "csiUcUsUiPcPsfQcQsQiQUcQUsQUiQPcQPsQf", OP_REV64>;
+def VREV32 : Inst<"dd", "csUcUsPcQcQsQUcQUsQPc", OP_REV32>;
+def VREV16 : Inst<"dd", "cUcPcQcQUcQPc", OP_REV16>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.28 Other single operand arithmetic
+def VABS : SInst<"dd", "csifQcQsQiQf">;
+def VQABS : SInst<"dd", "csiQcQsQi">;
+def VNEG : Inst<"dd", "csifQcQsQiQf", OP_NEG>;
+def VQNEG : SInst<"dd", "csiQcQsQi">;
+def VCLS : SInst<"dd", "csiQcQsQi">;
+def VCLZ : IInst<"dd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VCNT : WInst<"dd", "UccPcQUcQcQPc">;
+def VRECPE : SInst<"dd", "fUiQfQUi">;
+def VRSQRTE : SInst<"dd", "fUiQfQUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.29 Logical operations
+def VMVN : Inst<"dd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc", OP_NOT>;
+def VAND : Inst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_AND>;
+def VORR : Inst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_OR>;
+def VEOR : Inst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_XOR>;
+def VBIC : Inst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ANDN>;
+def VORN : Inst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ORN>;
+def VBSL : Inst<"dudd", "csilUcUsUiUlfPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPs", OP_SEL>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.30 Transposition operations
+def VTRN: WInst<"2dd", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">;
+def VZIP: WInst<"2dd", "csUcUsfPcPsQcQsQiQUcQUsQUiQfQPcQPs">;
+def VUZP: WInst<"2dd", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.31 Vector reinterpret cast operations
diff --git a/include/clang/Checker/AnalysisConsumer.h b/include/clang/Checker/AnalysisConsumer.h
new file mode 100644
index 000000000000..c236766f0ac9
--- /dev/null
+++ b/include/clang/Checker/AnalysisConsumer.h
@@ -0,0 +1,35 @@
+//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains the functions necessary for a front-end to run various
+// analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CHECKER_ANALYSISCONSUMER_H
+#define LLVM_CLANG_CHECKER_ANALYSISCONSUMER_H
+
+#include <string>
+
+namespace clang {
+
+class AnalyzerOptions;
+class ASTConsumer;
+class Preprocessor;
+
+/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
+/// analysis passes. (The set of analyses run is controlled by command-line
+/// options.)
+ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp,
+ const std::string &output,
+ const AnalyzerOptions& Opts);
+
+}
+
+#endif
diff --git a/include/clang/Checker/BugReporter/BugReporter.h b/include/clang/Checker/BugReporter/BugReporter.h
index 5b65d52a9a96..3749b43d7e23 100644
--- a/include/clang/Checker/BugReporter/BugReporter.h
+++ b/include/clang/Checker/BugReporter/BugReporter.h
@@ -70,6 +70,7 @@ protected:
virtual void Profile(llvm::FoldingSetNodeID& hash) const {
hash.AddInteger(getLocation().getRawEncoding());
+ hash.AddString(Description);
}
public:
diff --git a/include/clang/Checker/FrontendActions.h b/include/clang/Checker/FrontendActions.h
new file mode 100644
index 000000000000..1c0bbb78ba8c
--- /dev/null
+++ b/include/clang/Checker/FrontendActions.h
@@ -0,0 +1,29 @@
+//===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CHECKER_FRONTENDACTIONS_H
+#define LLVM_CLANG_CHECKER_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class AnalysisAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PathDiagnosticClients.h b/include/clang/Checker/PathDiagnosticClients.h
index f8d2eebeb687..d3aa3b211433 100644
--- a/include/clang/Frontend/PathDiagnosticClients.h
+++ b/include/clang/Checker/PathDiagnosticClients.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_PATH_DIAGNOSTIC_CLIENTS_H
-#define LLVM_CLANG_FRONTEND_PATH_DIAGNOSTIC_CLiENTS_H
+#ifndef LLVM_CLANG_CHECKER_PATH_DIAGNOSTIC_CLIENTS_H
+#define LLVM_CLANG_CHECKER_PATH_DIAGNOSTIC_CLiENTS_H
#include <string>
diff --git a/include/clang/Checker/PathSensitive/Checker.h b/include/clang/Checker/PathSensitive/Checker.h
index 8cb9cc8337c6..49dc3fa7dc44 100644
--- a/include/clang/Checker/PathSensitive/Checker.h
+++ b/include/clang/Checker/PathSensitive/Checker.h
@@ -38,16 +38,20 @@ class CheckerContext {
const unsigned size;
bool DoneEvaluating; // FIXME: This is not a permanent API change.
public:
+ bool *respondsToCallback;
+public:
CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
GRExprEngine &eng, ExplodedNode *pred,
const void *tag, ProgramPoint::Kind K,
+ bool *respondsToCB = 0,
const Stmt *stmt = 0, const GRState *st = 0)
: Dst(dst), B(builder), Eng(eng), Pred(pred),
OldSink(B.BuildSinks),
OldTag(B.Tag, tag),
OldPointKind(B.PointKind, K),
OldHasGen(B.HasGeneratedNode),
- ST(st), statement(stmt), size(Dst.size()) {}
+ ST(st), statement(stmt), size(Dst.size()),
+ respondsToCallback(respondsToCB) {}
~CheckerContext();
@@ -144,6 +148,7 @@ public:
// If the 'state' is not new, we need to check if the cached state 'ST'
// is new.
if (state != getState() || (ST && ST != B.GetState(Pred)))
+ // state is new or equals to ST.
GenerateNode(state, true);
else
Dst.Add(Pred);
@@ -188,10 +193,11 @@ private:
GRStmtNodeBuilder &Builder,
GRExprEngine &Eng,
const Stmt *S,
- ExplodedNode *Pred, void *tag, bool isPrevisit) {
+ ExplodedNode *Pred, void *tag, bool isPrevisit,
+ bool& respondsToCallback) {
CheckerContext C(Dst, Builder, Eng, Pred, tag,
isPrevisit ? ProgramPoint::PreStmtKind :
- ProgramPoint::PostStmtKind, S);
+ ProgramPoint::PostStmtKind, &respondsToCallback, S);
if (isPrevisit)
_PreVisit(C, S);
else
@@ -202,7 +208,7 @@ private:
GRExprEngine &Eng, const ObjCMessageExpr *ME,
ExplodedNode *Pred, const GRState *state, void *tag) {
CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
- ME, state);
+ 0, ME, state);
return EvalNilReceiver(C, ME);
}
@@ -210,7 +216,7 @@ private:
GRExprEngine &Eng, const CallExpr *CE,
ExplodedNode *Pred, void *tag) {
CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
- CE);
+ 0, CE);
return EvalCallExpr(C, CE);
}
@@ -223,7 +229,7 @@ private:
bool isPrevisit) {
CheckerContext C(Dst, Builder, Eng, Pred, tag,
isPrevisit ? ProgramPoint::PreStmtKind :
- ProgramPoint::PostStmtKind, StoreE);
+ ProgramPoint::PostStmtKind, 0, StoreE);
assert(isPrevisit && "Only previsit supported for now.");
PreVisitBind(C, AssignE, StoreE, location, val);
}
@@ -238,7 +244,7 @@ private:
void *tag, bool isLoad) {
CheckerContext C(Dst, Builder, Eng, Pred, tag,
isLoad ? ProgramPoint::PreLoadKind :
- ProgramPoint::PreStoreKind, S, state);
+ ProgramPoint::PreStoreKind, 0, S, state);
VisitLocation(C, S, location);
}
@@ -246,8 +252,8 @@ private:
GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
SymbolReaper &SymReaper, void *tag) {
CheckerContext C(Dst, Builder, Eng, Pred, tag,
- ProgramPoint::PostPurgeDeadSymbolsKind, S);
- EvalDeadSymbols(C, S, SymReaper);
+ ProgramPoint::PostPurgeDeadSymbolsKind, 0, S);
+ EvalDeadSymbols(C, SymReaper);
}
public:
@@ -257,8 +263,7 @@ public:
virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
const Stmt *StoreE, SVal location, SVal val) {}
- virtual void EvalDeadSymbols(CheckerContext &C, const Stmt *S,
- SymbolReaper &SymReaper) {}
+ virtual void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) {}
virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
GRExprEngine &Eng) {}
@@ -278,6 +283,9 @@ public:
bool Assumption) {
return state;
}
+
+ virtual void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B,
+ bool hasWorkRemaining) {}
};
} // end clang namespace
diff --git a/include/clang/Checker/PathSensitive/CheckerVisitor.h b/include/clang/Checker/PathSensitive/CheckerVisitor.h
index 72f0ae1375e8..e2ba89bca1b8 100644
--- a/include/clang/Checker/PathSensitive/CheckerVisitor.h
+++ b/include/clang/Checker/PathSensitive/CheckerVisitor.h
@@ -79,8 +79,13 @@ break;
}
}
- void PreVisitStmt(CheckerContext &C, const Stmt *S) {}
- void PostVisitStmt(CheckerContext &C, const Stmt *S) {}
+ void PreVisitStmt(CheckerContext &C, const Stmt *S) {
+ *C.respondsToCallback = false;
+ }
+
+ void PostVisitStmt(CheckerContext &C, const Stmt *S) {
+ *C.respondsToCallback = false;
+ }
void PreVisitCastExpr(CheckerContext &C, const CastExpr *E) {
static_cast<ImplClass*>(this)->PreVisitStmt(C, E);
diff --git a/include/clang/Checker/PathSensitive/Environment.h b/include/clang/Checker/PathSensitive/Environment.h
index b9bbebc652f2..2981731f863c 100644
--- a/include/clang/Checker/PathSensitive/Environment.h
+++ b/include/clang/Checker/PathSensitive/Environment.h
@@ -86,7 +86,7 @@ public:
Environment BindExpr(Environment Env, const Stmt *S, SVal V,
bool Invalidate);
- Environment RemoveDeadBindings(Environment Env, const Stmt *S,
+ Environment RemoveDeadBindings(Environment Env,
SymbolReaper &SymReaper, const GRState *ST,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
};
diff --git a/include/clang/Checker/PathSensitive/ExplodedGraph.h b/include/clang/Checker/PathSensitive/ExplodedGraph.h
index c09c89312e10..c875a2308ba3 100644
--- a/include/clang/Checker/PathSensitive/ExplodedGraph.h
+++ b/include/clang/Checker/PathSensitive/ExplodedGraph.h
@@ -36,7 +36,6 @@ namespace clang {
class GRState;
class CFG;
-class ASTContext;
class ExplodedGraph;
//===----------------------------------------------------------------------===//
@@ -240,9 +239,6 @@ protected:
/// and successor groups.
BumpVectorContext BVC;
- /// Ctx - The ASTContext used to "interpret" CodeDecl.
- ASTContext& Ctx;
-
/// NumNodes - The number of nodes in the graph.
unsigned NumNodes;
@@ -256,7 +252,7 @@ public:
bool* IsNew = 0);
ExplodedGraph* MakeEmptyGraph() const {
- return new ExplodedGraph(Ctx);
+ return new ExplodedGraph();
}
/// addRoot - Add an untyped node to the set of roots.
@@ -271,7 +267,7 @@ public:
return V;
}
- ExplodedGraph(ASTContext& ctx) : Ctx(ctx), NumNodes(0) {}
+ ExplodedGraph() : NumNodes(0) {}
~ExplodedGraph() {}
@@ -318,8 +314,6 @@ public:
llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); }
BumpVectorContext &getNodeAllocator() { return BVC; }
- ASTContext& getContext() { return Ctx; }
-
typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
std::pair<ExplodedGraph*, InterExplodedGraphMap*>
diff --git a/include/clang/Checker/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h
index 2d8afeeb0da6..7f101dca97e5 100644
--- a/include/clang/Checker/PathSensitive/GRCoreEngine.h
+++ b/include/clang/Checker/PathSensitive/GRCoreEngine.h
@@ -57,6 +57,10 @@ class GRCoreEngine {
/// These are used to record for key nodes in the ExplodedGraph the
/// number of times different CFGBlocks have been visited along a path.
GRBlockCounter::Factory BCounterFactory;
+
+ /// A flag that indicates whether paths were halted because
+ /// ProcessBlockEntrace returned false.
+ bool BlockAborted;
void GenerateNode(const ProgramPoint& Loc, const GRState* State,
ExplodedNode* Pred);
@@ -105,17 +109,19 @@ private:
public:
/// Construct a GRCoreEngine object to analyze the provided CFG using
/// a DFS exploration of the exploded graph.
- GRCoreEngine(ASTContext& ctx, GRSubEngine& subengine)
- : SubEngine(subengine), G(new ExplodedGraph(ctx)),
+ GRCoreEngine(GRSubEngine& subengine)
+ : SubEngine(subengine), G(new ExplodedGraph()),
WList(GRWorkList::MakeBFS()),
- BCounterFactory(G->getAllocator()) {}
+ BCounterFactory(G->getAllocator()),
+ BlockAborted(false) {}
/// Construct a GRCoreEngine object to analyze the provided CFG and to
/// use the provided worklist object to execute the worklist algorithm.
/// The GRCoreEngine object assumes ownership of 'wlist'.
- GRCoreEngine(ASTContext& ctx, GRWorkList* wlist, GRSubEngine& subengine)
- : SubEngine(subengine), G(new ExplodedGraph(ctx)), WList(wlist),
- BCounterFactory(G->getAllocator()) {}
+ GRCoreEngine(GRWorkList* wlist, GRSubEngine& subengine)
+ : SubEngine(subengine), G(new ExplodedGraph()), WList(wlist),
+ BCounterFactory(G->getAllocator()),
+ BlockAborted(false) {}
~GRCoreEngine() {
delete WList;
diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h
index ac407f6933c8..8eaf3f4a97d7 100644
--- a/include/clang/Checker/PathSensitive/GRExprEngine.h
+++ b/include/clang/Checker/PathSensitive/GRExprEngine.h
@@ -16,6 +16,7 @@
#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
#define LLVM_CLANG_ANALYSIS_GREXPRENGINE
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
#include "clang/Checker/PathSensitive/GRSubEngine.h"
#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/GRState.h"
@@ -75,14 +76,25 @@ class GRExprEngine : public GRSubEngine {
llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor;
typedef llvm::DenseMap<void *, unsigned> CheckerMap;
- CheckerMap CheckerM;
-
typedef std::vector<std::pair<void *, Checker*> > CheckersOrdered;
+ typedef llvm::DenseMap<std::pair<unsigned, unsigned>, CheckersOrdered *>
+ CheckersOrderedCache;
+
+ /// A registration map from checker tag to the index into the
+ /// ordered checkers vector.
+ CheckerMap CheckerM;
+
+ /// An ordered vector of checkers that are called when evaluating
+ /// various expressions and statements.
CheckersOrdered Checkers;
- /// BR - The BugReporter associated with this engine. It is important that
- // 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.
+ /// A map used for caching the checkers that respond to the callback for
+ /// a particular statement and visitation order.
+ CheckersOrderedCache COCache;
+
+ /// The BugReporter associated with this engine. It is important that
+ /// 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;
@@ -106,7 +118,7 @@ public:
}
/// getContext - Return the ASTContext associated with this analysis.
- ASTContext& getContext() const { return G.getContext(); }
+ ASTContext& getContext() const { return AMgr.getASTContext(); }
AnalysisManager &getAnalysisManager() const { return AMgr; }
@@ -178,12 +190,15 @@ public:
/// nodes when the control reaches the end of a function.
void ProcessEndPath(GREndPathNodeBuilder& builder);
- // Generate the entry node of the callee.
+ /// Generate the entry node of the callee.
void ProcessCallEnter(GRCallEnterNodeBuilder &builder);
- // Generate the first post callsite node.
+ /// Generate the first post callsite node.
void ProcessCallExit(GRCallExitNodeBuilder &builder);
+ /// Called by GRCoreEngine when the analysis worklist has terminated.
+ void ProcessEndWorklist(bool hasWorkRemaining);
+
/// EvalAssume - Callback function invoked by the ConstraintManager when
/// making assumptions about state values.
const GRState *ProcessAssume(const GRState *state, SVal cond, bool assumption);
diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h
index 25ba1f85fdff..67a2caf06a13 100644
--- a/include/clang/Checker/PathSensitive/GRState.h
+++ b/include/clang/Checker/PathSensitive/GRState.h
@@ -211,16 +211,18 @@ public:
const GRState *bindLoc(SVal location, SVal V) const;
+ const GRState *bindDefault(SVal loc, SVal V) const;
+
const GRState *unbindLoc(Loc LV) const;
/// Get the lvalue for a variable reference.
- SVal getLValue(const VarDecl *D, const LocationContext *LC) const;
+ Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
/// Get the lvalue for a StringLiteral.
- SVal getLValue(const StringLiteral *literal) const;
+ Loc getLValue(const StringLiteral *literal) const;
- SVal getLValue(const CompoundLiteralExpr *literal,
- const LocationContext *LC) const;
+ Loc getLValue(const CompoundLiteralExpr *literal,
+ const LocationContext *LC) const;
/// Get the lvalue for an ivar reference.
SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
@@ -446,7 +448,7 @@ public:
StoreManager& getStoreManager() { return *StoreMgr; }
ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
- const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
+ const GRState* RemoveDeadBindings(const GRState* St,
const StackFrameContext *LCtx,
SymbolReaper& SymReaper);
@@ -468,9 +470,6 @@ public:
const GRState* getPersistentState(GRState& Impl);
- bool isEqual(const GRState* state, const Expr* Ex, const llvm::APSInt& V);
- bool isEqual(const GRState* state, const Expr* Ex, uint64_t);
-
//==---------------------------------------------------------------------==//
// Generic Data Map methods.
//==---------------------------------------------------------------------==//
@@ -620,16 +619,22 @@ inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
}
-inline SVal GRState::getLValue(const VarDecl* VD,
+inline const GRState *GRState::bindDefault(SVal loc, SVal V) const {
+ const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion();
+ Store new_store = getStateManager().StoreMgr->BindDefault(St, R, V);
+ return makeWithStore(new_store);
+}
+
+inline Loc GRState::getLValue(const VarDecl* VD,
const LocationContext *LC) const {
return getStateManager().StoreMgr->getLValueVar(VD, LC);
}
-inline SVal GRState::getLValue(const StringLiteral *literal) const {
+inline Loc GRState::getLValue(const StringLiteral *literal) const {
return getStateManager().StoreMgr->getLValueString(literal);
}
-inline SVal GRState::getLValue(const CompoundLiteralExpr *literal,
+inline Loc GRState::getLValue(const CompoundLiteralExpr *literal,
const LocationContext *LC) const {
return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
}
diff --git a/include/clang/Checker/PathSensitive/GRSubEngine.h b/include/clang/Checker/PathSensitive/GRSubEngine.h
index d2e7457ea93d..90a41d7c093f 100644
--- a/include/clang/Checker/PathSensitive/GRSubEngine.h
+++ b/include/clang/Checker/PathSensitive/GRSubEngine.h
@@ -41,27 +41,27 @@ public:
virtual GRStateManager& getStateManager() = 0;
- /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
- /// nodes by processing the 'effects' of a block-level statement.
+ /// Called by GRCoreEngine. Used to generate new successor
+ /// nodes by processing the 'effects' of a block-level statement.
virtual void ProcessStmt(CFGElement E, GRStmtNodeBuilder& builder) = 0;
- /// ProcessBlockEntrance - Called by GRCoreEngine when start processing
- /// a CFGBlock. This method returns true if the analysis should continue
- /// exploring the given path, and false otherwise.
+ /// Called by GRCoreEngine when start processing
+ /// a CFGBlock. This method returns true if the analysis should continue
+ /// exploring the given path, and false otherwise.
virtual bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
GRBlockCounter BC) = 0;
- /// ProcessBranch - Called by GRCoreEngine. Used to generate successor
+ /// Called by GRCoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
virtual void ProcessBranch(Stmt* Condition, Stmt* Term,
GRBranchNodeBuilder& builder) = 0;
- /// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a computed goto jump.
+ /// Called by GRCoreEngine. Used to generate successor
+ /// nodes by processing the 'effects' of a computed goto jump.
virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) = 0;
- /// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a switch statement.
+ /// Called by GRCoreEngine. Used to generate successor
+ /// nodes by processing the 'effects' of a switch statement.
virtual void ProcessSwitch(GRSwitchNodeBuilder& builder) = 0;
/// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
@@ -74,10 +74,14 @@ public:
// Generate the first post callsite node.
virtual void ProcessCallExit(GRCallExitNodeBuilder &builder) = 0;
- /// EvalAssume - Called by ConstraintManager. Used to call checker-specific
- /// logic for handling assumptions on symbolic values.
+ /// 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;
+
+ /// Called by GRCoreEngine when the analysis worklist is either empty or the
+ // maximum number of analysis steps have been reached.
+ virtual void ProcessEndWorklist(bool hasWorkRemaining) = 0;
};
}
diff --git a/include/clang/Checker/PathSensitive/GRTransferFuncs.h b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
index 13325edea778..374f99820bd0 100644
--- a/include/clang/Checker/PathSensitive/GRTransferFuncs.h
+++ b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
@@ -66,7 +66,7 @@ public:
GRExprEngine& Engine,
GRStmtNodeBuilder& Builder,
ExplodedNode* Pred,
- Stmt* S, const GRState* state,
+ const GRState* state,
SymbolReaper& SymReaper) {}
// Return statements.
diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h
index 2ab3b420c313..feb4b7218a7e 100644
--- a/include/clang/Checker/PathSensitive/MemRegion.h
+++ b/include/clang/Checker/PathSensitive/MemRegion.h
@@ -34,7 +34,9 @@ class MemRegionManager;
class MemSpaceRegion;
class LocationContext;
class StackFrameContext;
+class ValueManager;
class VarRegion;
+class CodeTextRegion;
//===----------------------------------------------------------------------===//
// Base region classes.
@@ -46,14 +48,17 @@ class MemRegion : public llvm::FoldingSetNode {
public:
enum Kind {
// Memory spaces.
- BEG_MEMSPACES,
- GenericMemSpaceRegionKind = BEG_MEMSPACES,
+ GenericMemSpaceRegionKind,
StackLocalsSpaceRegionKind,
StackArgumentsSpaceRegionKind,
HeapSpaceRegionKind,
UnknownSpaceRegionKind,
- GlobalsSpaceRegionKind,
- END_MEMSPACES = GlobalsSpaceRegionKind,
+ NonStaticGlobalSpaceRegionKind,
+ StaticGlobalSpaceRegionKind,
+ BEG_GLOBAL_MEMSPACES = NonStaticGlobalSpaceRegionKind,
+ END_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
+ BEG_MEMSPACES = GenericMemSpaceRegionKind,
+ END_MEMSPACES = StaticGlobalSpaceRegionKind,
// Untyped regions.
SymbolicRegionKind,
AllocaRegionKind,
@@ -146,13 +151,48 @@ public:
};
class GlobalsSpaceRegion : public MemSpaceRegion {
+protected:
+ GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
+ : MemSpaceRegion(mgr, k) {}
+public:
+ static bool classof(const MemRegion *R) {
+ Kind k = R->getKind();
+ return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
+ }
+};
+
+class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
friend class MemRegionManager;
- GlobalsSpaceRegion(MemRegionManager *mgr)
- : MemSpaceRegion(mgr, GlobalsSpaceRegionKind) {}
+ const CodeTextRegion *CR;
+
+ StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
+ : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
+
+public:
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
+ const CodeTextRegion *getCodeRegion() const { return CR; }
+
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == StaticGlobalSpaceRegionKind;
+ }
+};
+
+class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
+ friend class MemRegionManager;
+
+ NonStaticGlobalSpaceRegion(MemRegionManager *mgr)
+ : GlobalsSpaceRegion(mgr, NonStaticGlobalSpaceRegionKind) {}
+
public:
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
static bool classof(const MemRegion *R) {
- return R->getKind() == GlobalsSpaceRegionKind;
+ return R->getKind() == NonStaticGlobalSpaceRegionKind;
}
};
@@ -232,6 +272,11 @@ public:
return superRegion;
}
+ /// getExtent - Returns the size of the region in bytes.
+ virtual DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const {
+ return UnknownVal();
+ }
+
MemRegionManager* getMemRegionManager() const;
bool isSubRegionOf(const MemRegion* R) const;
@@ -288,6 +333,8 @@ public:
bool isBoundable() const { return true; }
+ DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
void Profile(llvm::FoldingSetNodeID& ID) const;
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex,
@@ -502,6 +549,8 @@ public:
bool isBoundable() const { return true; }
+ DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
void Profile(llvm::FoldingSetNodeID& ID) const;
static void ProfileRegion(llvm::FoldingSetNodeID& ID,
@@ -536,6 +585,8 @@ public:
return Str->getType();
}
+ DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
bool isBoundable() const { return false; }
void Profile(llvm::FoldingSetNodeID& ID) const {
@@ -595,6 +646,8 @@ public:
const Decl* getDecl() const { return D; }
void Profile(llvm::FoldingSetNodeID& ID) const;
+ DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
static bool classof(const MemRegion* R) {
unsigned k = R->getKind();
return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
@@ -679,6 +732,8 @@ public:
return C.getCanonicalType(getDecl()->getType());
}
+ DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD,
const MemRegion* superRegion) {
DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
@@ -793,12 +848,14 @@ class MemRegionManager {
llvm::BumpPtrAllocator& A;
llvm::FoldingSet<MemRegion> Regions;
- GlobalsSpaceRegion *globals;
+ NonStaticGlobalSpaceRegion *globals;
llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
StackLocalsSpaceRegions;
llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
StackArgumentsSpaceRegions;
+ llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
+ StaticsGlobalSpaceRegions;
HeapSpaceRegion *heap;
UnknownSpaceRegion *unknown;
@@ -825,8 +882,8 @@ public:
getStackArgumentsRegion(const StackFrameContext *STC);
/// getGlobalsRegion - Retrieve the memory region associated with
- /// all global variables.
- const GlobalsSpaceRegion *getGlobalsRegion();
+ /// global variables.
+ const GlobalsSpaceRegion *getGlobalsRegion(const CodeTextRegion *R = 0);
/// getHeapRegion - Retrieve the memory region associated with the
/// generic "heap".
diff --git a/include/clang/Checker/PathSensitive/SVals.h b/include/clang/Checker/PathSensitive/SVals.h
index 040db831b8c0..55fd3ea5c929 100644
--- a/include/clang/Checker/PathSensitive/SVals.h
+++ b/include/clang/Checker/PathSensitive/SVals.h
@@ -98,6 +98,8 @@ public:
bool isConstant() const;
+ bool isConstant(int I) const;
+
bool isZeroConstant() const;
/// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
@@ -109,7 +111,7 @@ public:
const FunctionDecl* getAsFunctionDecl() const;
/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
- /// wraps a symbol, return that SymbolRef. Otherwise return a SymbolData*
+ /// wraps a symbol, return that SymbolRef. Otherwise return NULL.
SymbolRef getAsLocSymbol() const;
/// Get the symbol in the SVal or its base region.
diff --git a/include/clang/Checker/PathSensitive/SValuator.h b/include/clang/Checker/PathSensitive/SValuator.h
index 9beb8cb08661..9192ca7b8614 100644
--- a/include/clang/Checker/PathSensitive/SValuator.h
+++ b/include/clang/Checker/PathSensitive/SValuator.h
@@ -47,11 +47,15 @@ public:
virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode Op,
NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
- virtual SVal EvalBinOpLL(BinaryOperator::Opcode Op, Loc lhs, Loc rhs,
- QualType resultTy) = 0;
+ virtual SVal EvalBinOpLL(const GRState *state, BinaryOperator::Opcode Op,
+ Loc lhs, Loc rhs, QualType resultTy) = 0;
virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
Loc lhs, NonLoc rhs, QualType resultTy) = 0;
+
+ /// getKnownValue - Evaluates a given SVal. If the SVal has only one possible
+ /// (integer) value, that value is returned. Otherwise, returns NULL.
+ virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V) = 0;
SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
SVal L, SVal R, QualType T);
diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h
index f3155b9aacd4..7a60ebb0838e 100644
--- a/include/clang/Checker/PathSensitive/Store.h
+++ b/include/clang/Checker/PathSensitive/Store.h
@@ -64,6 +64,10 @@ public:
/// to the location given for \c loc.
virtual Store Bind(Store store, Loc loc, SVal val) = 0;
+ virtual Store BindDefault(Store store, const MemRegion *R, SVal V) {
+ return store;
+ }
+
virtual Store Remove(Store St, Loc L) = 0;
/// BindCompoundLiteral - Return the store that has the bindings currently
@@ -87,16 +91,16 @@ public:
// caller's responsibility to 'delete' the returned map.
virtual SubRegionMap *getSubRegionMap(Store store) = 0;
- virtual SVal getLValueVar(const VarDecl *VD, const LocationContext *LC) {
+ virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) {
return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
}
- virtual SVal getLValueString(const StringLiteral* S) {
+ virtual Loc getLValueString(const StringLiteral* S) {
return ValMgr.makeLoc(MRMgr.getStringRegion(S));
}
- SVal getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
- const LocationContext *LC) {
+ Loc getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
+ const LocationContext *LC) {
return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
}
@@ -110,7 +114,8 @@ public:
virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base);
- // FIXME: Make out-of-line.
+ // FIXME: This should soon be eliminated altogether; clients should deal with
+ // region extents directly.
virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state,
const MemRegion *region,
QualType EleTy) {
@@ -144,7 +149,7 @@ public:
return UnknownVal();
}
- virtual const GRState *RemoveDeadBindings(GRState &state, Stmt* Loc,
+ virtual const GRState *RemoveDeadBindings(GRState &state,
const StackFrameContext *LCtx,
SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
@@ -164,18 +169,8 @@ public:
const MemRegion * const *Begin,
const MemRegion * const *End,
const Expr *E, unsigned Count,
- InvalidatedSymbols *IS);
-
- // FIXME: Make out-of-line.
- virtual const GRState *setExtent(const GRState *state,
- const MemRegion *region, SVal extent) {
- return state;
- }
-
- virtual llvm::Optional<SVal> getExtent(const GRState *state,
- const MemRegion *R) {
- return llvm::Optional<SVal>();
- }
+ InvalidatedSymbols *IS,
+ bool invalidateGlobals) = 0;
/// EnterStackFrame - Let the StoreManager to do something when execution
/// engine is about to execute into a callee.
diff --git a/include/clang/Checker/PathSensitive/SymbolManager.h b/include/clang/Checker/PathSensitive/SymbolManager.h
index dea877c0657f..ffbd2892499e 100644
--- a/include/clang/Checker/PathSensitive/SymbolManager.h
+++ b/include/clang/Checker/PathSensitive/SymbolManager.h
@@ -31,6 +31,7 @@ namespace clang {
class ASTContext;
class BasicValueFactory;
class MemRegion;
+ class SubRegion;
class TypedRegion;
class VarRegion;
class StackFrameContext;
@@ -38,7 +39,7 @@ namespace clang {
class SymExpr : public llvm::FoldingSetNode {
public:
enum Kind { BEGIN_SYMBOLS,
- RegionValueKind, ConjuredKind, DerivedKind,
+ RegionValueKind, ConjuredKind, DerivedKind, ExtentKind,
END_SYMBOLS,
SymIntKind, SymSymKind };
private:
@@ -189,6 +190,34 @@ public:
}
};
+class SymbolExtent : public SymbolData {
+ const SubRegion *R;
+
+public:
+ SymbolExtent(SymbolID sym, const SubRegion *r)
+ : SymbolData(ExtentKind, sym), R(r) {}
+
+ const SubRegion *getRegion() const { return R; }
+
+ QualType getType(ASTContext&) const;
+
+ void dumpToStream(llvm::raw_ostream &os) const;
+
+ static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) {
+ profile.AddInteger((unsigned) ExtentKind);
+ profile.AddPointer(R);
+ }
+
+ virtual void Profile(llvm::FoldingSetNodeID& profile) {
+ Profile(profile, R);
+ }
+
+ // Implement isa<T> support.
+ static inline bool classof(const SymExpr* SE) {
+ return SE->getKind() == ExtentKind;
+ }
+};
+
// SymIntExpr - Represents symbolic expression like 'x' + 3.
class SymIntExpr : public SymExpr {
const SymExpr *LHS;
@@ -305,6 +334,8 @@ public:
const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol,
const TypedRegion *R);
+ const SymbolExtent *getExtentSymbol(const SubRegion *R);
+
const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
const llvm::APSInt& rhs, QualType t);
@@ -330,21 +361,23 @@ class SymbolReaper {
SetTy TheLiving;
SetTy TheDead;
const LocationContext *LCtx;
+ const Stmt *Loc;
SymbolManager& SymMgr;
public:
- SymbolReaper(const LocationContext *ctx, SymbolManager& symmgr)
- : LCtx(ctx), SymMgr(symmgr) {}
+ SymbolReaper(const LocationContext *ctx, const Stmt *s, SymbolManager& symmgr)
+ : LCtx(ctx), Loc(s), SymMgr(symmgr) {}
~SymbolReaper() {}
const LocationContext *getLocationContext() const { return LCtx; }
+ const Stmt *getCurrentStatement() const { return Loc; }
bool isLive(SymbolRef sym);
- bool isLive(const Stmt* Loc, const Stmt* ExprVal) const;
+ bool isLive(const Stmt *ExprVal) const;
- bool isLive(const Stmt* Loc, const VarRegion *VR) const;
+ bool isLive(const VarRegion *VR) const;
void markLive(SymbolRef sym);
bool maybeDead(SymbolRef sym);
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
new file mode 100644
index 000000000000..abcef8130dbc
--- /dev/null
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -0,0 +1,37 @@
+//===--- BackendUtil.h - LLVM Backend Utilities -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_BACKEND_UTIL_H
+#define LLVM_CLANG_CODEGEN_BACKEND_UTIL_H
+
+namespace llvm {
+ class Module;
+ class raw_ostream;
+}
+
+namespace clang {
+ class Diagnostic;
+ class CodeGenOptions;
+ class TargetOptions;
+
+ enum BackendAction {
+ Backend_EmitAssembly, ///< Emit native assembly files
+ Backend_EmitBC, ///< Emit LLVM bitcode files
+ Backend_EmitLL, ///< Emit human-readable LLVM assembly
+ Backend_EmitNothing, ///< Don't emit anything (benchmarking mode)
+ Backend_EmitMCNull, ///< Run CodeGen, but don't emit anything
+ Backend_EmitObj ///< Emit native object files
+ };
+
+ void EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts,
+ const TargetOptions &TOpts, llvm::Module *M,
+ BackendAction Action, llvm::raw_ostream *OS);
+}
+
+#endif
diff --git a/include/clang/Frontend/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
index dfc117a0b06c..cecfcda461bb 100644
--- a/include/clang/Frontend/CodeGenAction.h
+++ b/include/clang/CodeGen/CodeGenAction.h
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
+#define LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
+
#include "clang/Frontend/FrontendAction.h"
#include "llvm/ADT/OwningPtr.h"
@@ -24,9 +27,13 @@ private:
protected:
CodeGenAction(unsigned _Act);
+ virtual bool hasIRSupport() const;
+
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile);
+ virtual void ExecuteAction();
+
virtual void EndSourceFileAction();
public:
@@ -68,3 +75,5 @@ public:
};
}
+
+#endif
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index 2a3aa6a90404..c45ad08716c6 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -33,6 +33,9 @@ namespace clang {
virtual llvm::Module* ReleaseModule() = 0;
};
+ /// CreateLLVMCodeGen - Create a CodeGenerator instance.
+ /// It is the responsibility of the caller to call delete on
+ /// the allocated CodeGenerator instance.
CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags,
const std::string &ModuleName,
const CodeGenOptions &CGO,
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index ab3162a04707..4b45c98313c4 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -51,9 +51,10 @@ public:
AssembleJobClass,
LinkJobClass,
LipoJobClass,
+ DsymutilJobClass,
JobClassFirst=PreprocessJobClass,
- JobClassLast=LipoJobClass
+ JobClassLast=DsymutilJobClass
};
static const char *getClassName(ActionClass AC);
@@ -211,6 +212,16 @@ public:
static bool classof(const LipoJobAction *) { return true; }
};
+class DsymutilJobAction : public JobAction {
+public:
+ DsymutilJobAction(ActionList &Inputs, types::ID Type);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == DsymutilJobClass;
+ }
+ static bool classof(const DsymutilJobAction *) { return true; }
+};
+
} // end namespace driver
} // end namespace clang
diff --git a/include/clang/Driver/Arg.h b/include/clang/Driver/Arg.h
index ebf40d45de4c..a52789e69929 100644
--- a/include/clang/Driver/Arg.h
+++ b/include/clang/Driver/Arg.h
@@ -10,14 +10,9 @@
#ifndef CLANG_DRIVER_ARG_H_
#define CLANG_DRIVER_ARG_H_
-#include "llvm/Support/Casting.h"
-using llvm::isa;
-using llvm::cast;
-using llvm::cast_or_null;
-using llvm::dyn_cast;
-using llvm::dyn_cast_or_null;
-
#include "Util.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include <vector>
#include <string>
@@ -34,19 +29,10 @@ namespace driver {
/// ArgList to provide efficient iteration over all instances of a
/// particular option.
class Arg {
- public:
- enum ArgClass {
- FlagClass = 0,
- PositionalClass,
- JoinedClass,
- SeparateClass,
- CommaJoinedClass,
- JoinedAndSeparateClass
- };
+ Arg(const Arg &); // DO NOT IMPLEMENT
+ void operator=(const Arg &); // DO NOT IMPLEMENT
private:
- ArgClass Kind;
-
/// The option this argument is an instance of.
const Option *Opt;
@@ -58,20 +44,24 @@ namespace driver {
/// ArgList.
unsigned Index;
- /// Flag indicating whether this argument was used to effect
- /// compilation; used for generating "argument unused"
- /// diagnostics.
- mutable bool Claimed;
+ /// Was this argument used to effect compilation; used for generating
+ /// "argument unused" diagnostics.
+ mutable unsigned Claimed : 1;
+
+ /// Does this argument own its values.
+ mutable unsigned OwnsValues : 1;
- protected:
- Arg(ArgClass Kind, const Option *Opt, unsigned Index,
- const Arg *BaseArg = 0);
+ /// The argument values, as C strings.
+ llvm::SmallVector<const char *, 2> Values;
public:
- Arg(const Arg &);
- virtual ~Arg();
+ Arg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
+ Arg(const Option *Opt, unsigned Index,
+ const char *Value0, const Arg *BaseArg = 0);
+ Arg(const Option *Opt, unsigned Index,
+ const char *Value0, const char *Value1, const Arg *BaseArg = 0);
+ ~Arg();
- ArgClass getKind() const { return Kind; }
const Option &getOption() const { return *Opt; }
unsigned getIndex() const { return Index; }
@@ -85,19 +75,32 @@ namespace driver {
BaseArg = _BaseArg;
}
+ bool getOwnsValues() const { return OwnsValues; }
+ void setOwnsValues(bool Value) const { OwnsValues = Value; }
+
bool isClaimed() const { return getBaseArg().Claimed; }
/// claim - Set the Arg claimed bit.
-
- // FIXME: We need to deal with derived arguments and set the bit
- // in the original argument; not the derived one.
void claim() const { getBaseArg().Claimed = true; }
- virtual unsigned getNumValues() const = 0;
- virtual const char *getValue(const ArgList &Args, unsigned N=0) const = 0;
+ unsigned getNumValues() const { return Values.size(); }
+ const char *getValue(const ArgList &Args, unsigned N=0) const {
+ return Values[N];
+ }
+
+ llvm::SmallVectorImpl<const char*> &getValues() {
+ return Values;
+ }
+
+ bool containsValue(llvm::StringRef Value) const {
+ for (unsigned i = 0, e = getNumValues(); i != e; ++i)
+ if (Values[i] == Value)
+ return true;
+ return false;
+ }
/// render - Append the argument onto the given array as strings.
- virtual void render(const ArgList &Args, ArgStringList &Output) const = 0;
+ void render(const ArgList &Args, ArgStringList &Output) const;
/// renderAsInput - Append the argument, render as an input, onto
/// the given array as strings. The distinction is that some
@@ -114,116 +117,6 @@ namespace driver {
std::string getAsString(const ArgList &Args) const;
};
- /// FlagArg - An argument with no value.
- class FlagArg : public Arg {
- public:
- FlagArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
-
- virtual void render(const ArgList &Args, ArgStringList &Output) const;
-
- virtual unsigned getNumValues() const { return 0; }
- virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
-
- static bool classof(const Arg *A) {
- return A->getKind() == Arg::FlagClass;
- }
- static bool classof(const FlagArg *) { return true; }
- };
-
- /// PositionalArg - A simple positional argument.
- class PositionalArg : public Arg {
- public:
- PositionalArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
-
- virtual void render(const ArgList &Args, ArgStringList &Output) const;
-
- virtual unsigned getNumValues() const { return 1; }
- virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
-
- static bool classof(const Arg *A) {
- return A->getKind() == Arg::PositionalClass;
- }
- static bool classof(const PositionalArg *) { return true; }
- };
-
- /// JoinedArg - A single value argument where the value is joined
- /// (suffixed) to the option.
- class JoinedArg : public Arg {
- public:
- JoinedArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
-
- virtual void render(const ArgList &Args, ArgStringList &Output) const;
-
- virtual unsigned getNumValues() const { return 1; }
- virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
-
- static bool classof(const Arg *A) {
- return A->getKind() == Arg::JoinedClass;
- }
- static bool classof(const JoinedArg *) { return true; }
- };
-
- /// SeparateArg - An argument where one or more values follow the
- /// option specifier immediately in the argument vector.
- class SeparateArg : public Arg {
- unsigned NumValues;
-
- public:
- SeparateArg(const Option *Opt, unsigned Index, unsigned NumValues,
- const Arg *BaseArg = 0);
-
- virtual void render(const ArgList &Args, ArgStringList &Output) const;
-
- virtual unsigned getNumValues() const { return NumValues; }
- virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
-
- static bool classof(const Arg *A) {
- return A->getKind() == Arg::SeparateClass;
- }
- static bool classof(const SeparateArg *) { return true; }
- };
-
- /// CommaJoinedArg - An argument with multiple values joined by
- /// commas and joined (suffixed) to the option specifier.
- ///
- /// The key point of this arg is that it renders its values into
- /// separate arguments, which allows it to be used as a generic
- /// mechanism for passing arguments through to tools.
- class CommaJoinedArg : public Arg {
- std::vector<std::string> Values;
-
- public:
- CommaJoinedArg(const Option *Opt, unsigned Index, const char *Str,
- const Arg *BaseArg = 0);
-
- virtual void render(const ArgList &Args, ArgStringList &Output) const;
-
- virtual unsigned getNumValues() const { return Values.size(); }
- virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
-
- static bool classof(const Arg *A) {
- return A->getKind() == Arg::CommaJoinedClass;
- }
- static bool classof(const CommaJoinedArg *) { return true; }
- };
-
- /// JoinedAndSeparateArg - An argument with both joined and separate
- /// values.
- class JoinedAndSeparateArg : public Arg {
- public:
- JoinedAndSeparateArg(const Option *Opt, unsigned Index,
- const Arg *BaseArg = 0);
-
- virtual void render(const ArgList &Args, ArgStringList &Output) const;
-
- virtual unsigned getNumValues() const { return 2; }
- virtual const char *getValue(const ArgList &Args, unsigned N=0) const;
-
- static bool classof(const Arg *A) {
- return A->getKind() == Arg::JoinedAndSeparateClass;
- }
- static bool classof(const JoinedAndSeparateArg *) { return true; }
- };
} // end namespace driver
} // end namespace clang
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
index 7a14ae84d466..16396daa60ef 100644
--- a/include/clang/Driver/ArgList.h
+++ b/include/clang/Driver/ArgList.h
@@ -52,9 +52,9 @@ namespace driver {
void SkipToNextArg();
public:
- typedef const Arg* value_type;
- typedef const Arg* reference;
- typedef const Arg* pointer;
+ typedef Arg * const * value_type;
+ typedef Arg * const & reference;
+ typedef Arg * const * pointer;
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
@@ -67,7 +67,7 @@ namespace driver {
operator const Arg*() { return *Current; }
reference operator*() const { return *Current; }
- pointer operator->() const { return *Current; }
+ pointer operator->() const { return Current; }
arg_iterator &operator++() {
++Current;
@@ -96,6 +96,10 @@ namespace driver {
/// check for the presence of Arg instances for a particular Option
/// and to iterate over groups of arguments.
class ArgList {
+ private:
+ ArgList(const ArgList &); // DO NOT IMPLEMENT
+ void operator=(const ArgList &); // DO NOT IMPLEMENT
+
public:
typedef llvm::SmallVector<Arg*, 16> arglist_type;
typedef arglist_type::iterator iterator;
@@ -104,11 +108,11 @@ namespace driver {
typedef arglist_type::const_reverse_iterator const_reverse_iterator;
private:
- /// The full list of arguments.
- arglist_type &Args;
+ /// The internal list of arguments.
+ arglist_type Args;
protected:
- ArgList(arglist_type &Args);
+ ArgList();
public:
virtual ~ArgList();
@@ -179,6 +183,11 @@ namespace driver {
/// getArgString - Return the input argument string at \arg Index.
virtual const char *getArgString(unsigned Index) const = 0;
+ /// getNumInputArgStrings - Return the number of original argument strings,
+ /// which are guaranteed to be the first strings in the argument string
+ /// list.
+ virtual unsigned getNumInputArgStrings() const = 0;
+
/// @}
/// @name Argument Lookup Utilities
/// @{
@@ -249,14 +258,16 @@ namespace driver {
}
const char *MakeArgString(const llvm::Twine &Str) const;
+ /// \brief Create an arg string for (\arg LHS + \arg RHS), reusing the
+ /// string at \arg Index if possible.
+ const char *GetOrMakeJoinedArgString(unsigned Index, llvm::StringRef LHS,
+ llvm::StringRef RHS) const;
+
/// @}
};
class InputArgList : public ArgList {
private:
- /// The internal list of arguments.
- arglist_type ActualArgs;
-
/// List of argument strings used by the contained Args.
///
/// This is mutable since we treat the ArgList as being the list
@@ -276,16 +287,15 @@ namespace driver {
public:
InputArgList(const char **ArgBegin, const char **ArgEnd);
- InputArgList(const ArgList &);
~InputArgList();
virtual const char *getArgString(unsigned Index) const {
return ArgStrings[Index];
}
- /// getNumInputArgStrings - Return the number of original input
- /// argument strings.
- unsigned getNumInputArgStrings() const { return NumInputArgStrings; }
+ virtual unsigned getNumInputArgStrings() const {
+ return NumInputArgStrings;
+ }
/// @name Arg Synthesis
/// @{
@@ -303,34 +313,71 @@ namespace driver {
/// DerivedArgList - An ordered collection of driver arguments,
/// whose storage may be in another argument list.
class DerivedArgList : public ArgList {
- InputArgList &BaseArgs;
-
- /// The internal list of arguments.
- arglist_type ActualArgs;
+ const InputArgList &BaseArgs;
/// The list of arguments we synthesized.
mutable arglist_type SynthesizedArgs;
- /// Is this only a proxy for the base ArgList?
- bool OnlyProxy;
-
public:
/// Construct a new derived arg list from \arg BaseArgs.
- ///
- /// \param OnlyProxy - If true, this is only a proxy for the base
- /// list (to adapt the type), and it's Args list is unused.
- DerivedArgList(InputArgList &BaseArgs, bool OnlyProxy);
+ DerivedArgList(const InputArgList &BaseArgs);
~DerivedArgList();
virtual const char *getArgString(unsigned Index) const {
return BaseArgs.getArgString(Index);
}
+ virtual unsigned getNumInputArgStrings() const {
+ return BaseArgs.getNumInputArgStrings();
+ }
+
+ const InputArgList &getBaseArgs() const {
+ return BaseArgs;
+ }
+
/// @name Arg Synthesis
/// @{
+ /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
+ /// (to be freed).
+ void AddSynthesizedArg(Arg *A) {
+ SynthesizedArgs.push_back(A);
+ }
+
virtual const char *MakeArgString(llvm::StringRef Str) const;
+ /// AddFlagArg - Construct a new FlagArg for the given option \arg Id and
+ /// append it to the argument list.
+ void AddFlagArg(const Arg *BaseArg, const Option *Opt) {
+ append(MakeFlagArg(BaseArg, Opt));
+ }
+
+ /// AddPositionalArg - Construct a new Positional arg for the given option
+ /// \arg Id, with the provided \arg Value and append it to the argument
+ /// list.
+ void AddPositionalArg(const Arg *BaseArg, const Option *Opt,
+ llvm::StringRef Value) {
+ append(MakePositionalArg(BaseArg, Opt, Value));
+ }
+
+
+ /// AddSeparateArg - Construct a new Positional arg for the given option
+ /// \arg Id, with the provided \arg Value and append it to the argument
+ /// list.
+ void AddSeparateArg(const Arg *BaseArg, const Option *Opt,
+ llvm::StringRef Value) {
+ append(MakeSeparateArg(BaseArg, Opt, Value));
+ }
+
+
+ /// AddJoinedArg - Construct a new Positional arg for the given option \arg
+ /// Id, with the provided \arg Value and append it to the argument list.
+ void AddJoinedArg(const Arg *BaseArg, const Option *Opt,
+ llvm::StringRef Value) {
+ append(MakeJoinedArg(BaseArg, Opt, Value));
+ }
+
+
/// MakeFlagArg - Construct a new FlagArg for the given option
/// \arg Id.
Arg *MakeFlagArg(const Arg *BaseArg, const Option *Opt) const;
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index fd8322b84370..7076f30995d0 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -18,6 +18,8 @@ include "OptParser.td"
// Target Options
//===----------------------------------------------------------------------===//
+def cxx_abi : Separate<"-cxx-abi">,
+ HelpText<"Target a particular C++ ABI type">;
def target_abi : Separate<"-target-abi">,
HelpText<"Target a particular ABI type">;
def target_cpu : Separate<"-target-cpu">,
@@ -79,6 +81,8 @@ def analyzer_display_progress : Flag<"-analyzer-display-progress">,
HelpText<"Emit verbose output about the analyzer's progress">;
def analyzer_experimental_checks : Flag<"-analyzer-experimental-checks">,
HelpText<"Use experimental path-sensitive checks">;
+def analyzer_idempotent_operation : Flag<"-analyzer-idempotent-operation">,
+ HelpText<"Use experimental path-sensitive idempotent operation checker">;
def analyzer_experimental_internal_checks :
Flag<"-analyzer-experimental-internal-checks">,
HelpText<"Use new default path-sensitive checks currently in testing">;
@@ -121,6 +125,8 @@ def fno_common : Flag<"-fno-common">,
HelpText<"Compile common globals like normal definitions">;
def no_implicit_float : Flag<"-no-implicit-float">,
HelpText<"Don't generate implicit floating point instructions (x86-only)">;
+def finstrument_functions : Flag<"-finstrument-functions">,
+ HelpText<"Generate calls to instrument function entry and exit">;
def fno_merge_all_constants : Flag<"-fno-merge-all-constants">,
HelpText<"Disallow merging of constants.">;
def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">,
@@ -145,6 +151,8 @@ def mlimit_float_precision : Separate<"-mlimit-float-precision">,
HelpText<"Limit float precision to the given value">;
def mno_zero_initialized_in_bss : Flag<"-mno-zero-initialized-in-bss">,
HelpText<"Do not put zero initialized data in the BSS">;
+def momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">,
+ HelpText<"Omit frame pointer setup for leaf functions.">;
def msoft_float : Flag<"-msoft-float">,
HelpText<"Use software floating point">;
def mrelax_all : Flag<"-mrelax-all">,
@@ -182,6 +190,9 @@ def fno_show_column : Flag<"-fno-show-column">,
HelpText<"Do not include column number on diagnostics">;
def fno_show_source_location : Flag<"-fno-show-source-location">,
HelpText<"Do not include source location information with diagnostics">;
+def fshow_overloads_EQ : Joined<"-fshow-overloads=">,
+ HelpText<"Which overload candidates to show when overload resolution fails: "
+ "best|all; defaults to all">;
def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">,
HelpText<"Do not include source line and caret with diagnostics">;
def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">,
@@ -259,8 +270,11 @@ def cxx_inheritance_view : Separate<"-cxx-inheritance-view">,
def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">;
def load : Separate<"-load">, MetaVarName<"<dsopath>">,
HelpText<"Load the named plugin (dynamic shared object)">;
-def plugin : Separate<"-plugin">,
+def plugin : Separate<"-plugin">, MetaVarName<"<name>">,
HelpText<"Use the named plugin action (use \"help\" to list available options)">;
+def plugin_arg : JoinedAndSeparate<"-plugin-arg-">,
+ MetaVarName<"<name> <arg>">,
+ HelpText<"Pass <arg> to plugin <name>">;
def resource_dir : Separate<"-resource-dir">,
HelpText<"The directory which holds the compiler resource files">;
def version : Flag<"-version">,
@@ -333,6 +347,8 @@ def rewrite_macros : Flag<"-rewrite-macros">,
def relocatable_pch : Flag<"-relocatable-pch">,
HelpText<"Whether to build a relocatable precompiled header">;
+def chained_pch : Flag<"-chained-pch">,
+ HelpText<"Whether to chain the new precompiled header to the old one.">;
def print_stats : Flag<"-print-stats">,
HelpText<"Print performance metrics and statistics">;
def ftime_report : Flag<"-ftime-report">,
@@ -395,6 +411,8 @@ def fno_operator_names : Flag<"-fno-operator-names">,
HelpText<"Do not treat C++ operator name keywords as synonyms for operators">;
def fno_signed_char : Flag<"-fno-signed-char">,
HelpText<"Char is unsigned">;
+def fno_spell_checking : Flag<"-fno-spell-checking">,
+ HelpText<"Disable spell-checking">;
def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">,
HelpText<"Don't use __cxa_atexit for calling destructors">;
def fconstant_string_class : Separate<"-fconstant-string-class">,
@@ -416,6 +434,8 @@ def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">,
HelpText<"enable objective-c's enhanced nonfragile abi">;
def ftrapv : Flag<"-ftrapv">,
HelpText<"Trap on integer overflow">;
+def fwrapv : Flag<"-fwrapv">,
+ HelpText<"Treat signed integer overflow as two's complement">;
def pic_level : Separate<"-pic-level">,
HelpText<"Value for __PIC__">;
def pthread : Flag<"-pthread">,
@@ -432,6 +452,8 @@ def stack_protector : Separate<"-stack-protector">,
HelpText<"Enable stack protectors">;
def fvisibility : Separate<"-fvisibility">,
HelpText<"Default symbol visibility">;
+def fvisibility_inlines_hidden : Flag<"-fvisibility-inlines-hidden">,
+ HelpText<"Give inline C++ member functions default visibility by default">;
def ftemplate_depth : Separate<"-ftemplate-depth">,
HelpText<"Maximum depth of recursive template instantiation">;
def trigraphs : Flag<"-trigraphs">,
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 56786a7ae2a3..5f062a121c6d 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -40,13 +40,18 @@ class Compilation {
/// The original (untranslated) input argument list.
InputArgList *Args;
+ /// The driver translated arguments. Note that toolchains may perform their
+ /// own argument translation.
+ DerivedArgList *TranslatedArgs;
+
/// The list of actions.
ActionList Actions;
/// The root list of jobs.
JobList Jobs;
- /// Cache of translated arguments for a particular tool chain.
+ /// Cache of translated arguments for a particular tool chain and bound
+ /// architecture.
llvm::DenseMap<std::pair<const ToolChain*, const char*>,
DerivedArgList*> TCArgs;
@@ -58,14 +63,16 @@ class Compilation {
public:
Compilation(const Driver &D, const ToolChain &DefaultToolChain,
- InputArgList *Args);
+ InputArgList *Args, DerivedArgList *TranslatedArgs);
~Compilation();
const Driver &getDriver() const { return TheDriver; }
const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
- const InputArgList &getArgs() const { return *Args; }
+ const InputArgList &getInputArgs() const { return *Args; }
+
+ const DerivedArgList &getArgs() const { return *TranslatedArgs; }
ActionList &getActions() { return Actions; }
const ActionList &getActions() const { return Actions; }
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 90c3a0dcdc18..153981f842d3 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -31,6 +31,7 @@ namespace driver {
class Action;
class ArgList;
class Compilation;
+ class DerivedArgList;
class HostInfo;
class InputArgList;
class InputInfo;
@@ -135,6 +136,11 @@ private:
std::list<std::string> TempFiles;
std::list<std::string> ResultFiles;
+private:
+ /// TranslateInputArgs - Create a new derived argument list from the input
+ /// arguments, after applying the standard argument translations.
+ DerivedArgList *TranslateInputArgs(const InputArgList &Args) const;
+
public:
Driver(llvm::StringRef _Name, llvm::StringRef _Dir,
llvm::StringRef _DefaultHostTriple,
diff --git a/include/clang/Driver/HostInfo.h b/include/clang/Driver/HostInfo.h
index ca1ee9aa7766..1b99a4459d16 100644
--- a/include/clang/Driver/HostInfo.h
+++ b/include/clang/Driver/HostInfo.h
@@ -76,6 +76,8 @@ const HostInfo *createOpenBSDHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createFreeBSDHostInfo(const Driver &D,
const llvm::Triple& Triple);
+const HostInfo *createMinixHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
const HostInfo *createDragonFlyHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createLinuxHostInfo(const Driver &D,
diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile
index b462aaa24bc9..d8291662a563 100644
--- a/include/clang/Driver/Makefile
+++ b/include/clang/Driver/Makefile
@@ -1,9 +1,9 @@
-LEVEL = ../../../../..
+CLANG_LEVEL := ../../..
BUILT_SOURCES = Options.inc CC1Options.inc CC1AsOptions.inc
TABLEGEN_INC_FILES_COMMON = 1
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
$(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang Driver Option tables with tblgen"
diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h
index edae75c9f057..e4a2eba578b8 100644
--- a/include/clang/Driver/OptTable.h
+++ b/include/clang/Driver/OptTable.h
@@ -33,6 +33,7 @@ namespace options {
}
class Arg;
+ class ArgList;
class InputArgList;
class Option;
@@ -150,7 +151,7 @@ namespace options {
/// \return - The parsed argument, or 0 if the argument is missing values
/// (in which case Index still points at the conceptual next argument string
/// to parse).
- Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const;
+ Arg *ParseOneArg(const ArgList &Args, unsigned &Index) const;
/// ParseArgs - Parse an list of arguments into an InputArgList.
///
diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h
index 08b94b1d797d..0864382cb3a6 100644
--- a/include/clang/Driver/Option.h
+++ b/include/clang/Driver/Option.h
@@ -21,7 +21,7 @@ using llvm::dyn_cast_or_null;
namespace clang {
namespace driver {
class Arg;
- class InputArgList;
+ class ArgList;
class OptionGroup;
/// Option - Abstract representation for a single form of driver
@@ -50,6 +50,13 @@ namespace driver {
JoinedAndSeparateClass
};
+ enum RenderStyleKind {
+ RenderCommaJoinedStyle,
+ RenderJoinedStyle,
+ RenderSeparateStyle,
+ RenderValuesStyle
+ };
+
private:
OptionClass Kind;
@@ -65,7 +72,7 @@ namespace driver {
/// Option that this is an alias for, if any.
const Option *Alias;
- /// Unsupported options will not be rejected.
+ /// Unsupported options will be rejected.
bool Unsupported : 1;
/// Treat this option like a linker input?
@@ -76,11 +83,8 @@ namespace driver {
// FIXME: We should ditch the render/renderAsInput distinction.
bool NoOptAsInput : 1;
- /// Always render this option as separate form its value.
- bool ForceSeparateRender : 1;
-
- /// Always render this option joined with its value.
- bool ForceJoinedRender : 1;
+ /// The style to using when rendering arguments parsed by this option.
+ unsigned RenderStyle : 2;
/// This option is only consumed by the driver.
bool DriverOption : 1;
@@ -109,11 +113,10 @@ namespace driver {
bool hasNoOptAsInput() const { return NoOptAsInput; }
void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
- bool hasForceSeparateRender() const { return ForceSeparateRender; }
- void setForceSeparateRender(bool Value) { ForceSeparateRender = Value; }
-
- bool hasForceJoinedRender() const { return ForceJoinedRender; }
- void setForceJoinedRender(bool Value) { ForceJoinedRender = Value; }
+ RenderStyleKind getRenderStyle() const {
+ return RenderStyleKind(RenderStyle);
+ }
+ void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; }
bool isDriverOption() const { return DriverOption; }
void setDriverOption(bool Value) { DriverOption = Value; }
@@ -151,7 +154,7 @@ namespace driver {
/// If the option accepts the current argument, accept() sets
/// Index to the position where argument parsing should resume
/// (even if the argument is missing values).
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const = 0;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0;
void dump() const;
@@ -164,7 +167,7 @@ namespace driver {
public:
OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::GroupClass;
@@ -179,7 +182,7 @@ namespace driver {
public:
InputOption(OptSpecifier ID);
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::InputClass;
@@ -192,7 +195,7 @@ namespace driver {
public:
UnknownOption(OptSpecifier ID);
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::UnknownClass;
@@ -207,7 +210,7 @@ namespace driver {
FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
const Option *Alias);
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::FlagClass;
@@ -220,7 +223,7 @@ namespace driver {
JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
const Option *Alias);
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::JoinedClass;
@@ -233,7 +236,7 @@ namespace driver {
SeparateOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias);
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::SeparateClass;
@@ -246,7 +249,7 @@ namespace driver {
CommaJoinedOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias);
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::CommaJoinedClass;
@@ -267,7 +270,7 @@ namespace driver {
unsigned getNumArgs() const { return NumArgs; }
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::MultiArgClass;
@@ -282,7 +285,7 @@ namespace driver {
JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias);
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::JoinedOrSeparateClass;
@@ -297,7 +300,7 @@ namespace driver {
JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias);
- virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+ virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
static bool classof(const Option *O) {
return O->getKind() == Option::JoinedAndSeparateClass;
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index a9a52c01f45b..96ec12215b40 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -124,11 +124,11 @@ def C : Flag<"-C">;
def D : JoinedOrSeparate<"-D">, Group<CompileOnly_Group>;
def E : Flag<"-E">, Flags<[DriverOption]>,
HelpText<"Only run the preprocessor">;
-def F : JoinedOrSeparate<"-F">;
+def F : JoinedOrSeparate<"-F">, Flags<[RenderJoined]>;
def H : Flag<"-H">;
def I_ : Flag<"-I-">, Group<I_Group>;
def I : JoinedOrSeparate<"-I">, Group<I_Group>;
-def L : JoinedOrSeparate<"-L">;
+def L : JoinedOrSeparate<"-L">, Flags<[RenderJoined]>;
def MD : Flag<"-MD">, Group<M_Group>;
def MF : JoinedOrSeparate<"-MF">, Group<M_Group>;
def MG : Flag<"-MG">, Group<M_Group>;
@@ -244,6 +244,7 @@ def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>;
def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>;
def fbuiltin_strcpy : Flag<"-fbuiltin-strcpy">, Group<f_Group>;
def fbuiltin : Flag<"-fbuiltin">, Group<f_Group>;
+def fcaret_diagnostics : Flag<"-fcaret-diagnostics">, Group<f_Group>;
def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior.">;
def fclasspath_EQ : Joined<"-fclasspath=">, Group<f_Group>;
@@ -267,6 +268,8 @@ def fencoding_EQ : Joined<"-fencoding=">, Group<f_Group>;
def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
def fhosted : Flag<"-fhosted">, Group<f_Group>;
+def ffast_math : Flag<"-ffast-math">, Group<clang_ignored_f_Group>;
+def ffinite_math_only : Flag<"-ffinite-math-only">, Group<clang_ignored_f_Group>;
def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>;
def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>;
@@ -275,6 +278,7 @@ def filelist : Separate<"-filelist">, Flags<[LinkerInput]>;
def findirect_virtual_calls : Flag<"-findirect-virtual-calls">, Group<f_Group>;
def finline_functions : Flag<"-finline-functions">, Group<clang_ignored_f_Group>;
def finline : Flag<"-finline">, Group<clang_ignored_f_Group>;
+def finstrument_functions : Flag<"-finstrument-functions">, Group<f_Group>;
def fkeep_inline_functions : Flag<"-fkeep-inline-functions">, Group<clang_ignored_f_Group>;
def flat__namespace : Flag<"-flat_namespace">;
def flax_vector_conversions : Flag<"-flax-vector-conversions">, Group<f_Group>;
@@ -307,6 +311,7 @@ def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_
def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
def fno_eliminate_unused_debug_symbols : Flag<"-fno-eliminate-unused-debug-symbols">, Group<f_Group>;
def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>;
+def fno_finite_math_only : Flag<"-fno-finite-math-only">, Group<clang_ignored_f_Group>;
def fno_gnu_keywords : Flag<"-fno-gnu-keywords">, Group<f_Group>;
def fno_inline_functions : Flag<"-fno-inline-functions">, Group<clang_ignored_f_Group>;
def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>;
@@ -321,6 +326,7 @@ def fno_pascal_strings : Flag<"-fno-pascal-strings">, Group<f_Group>;
def fno_rtti : Flag<"-fno-rtti">, Group<f_Group>;
def fno_show_column : Flag<"-fno-show-column">, Group<f_Group>;
def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>;
+def fno_spell_checking : Flag<"-fno-spell-checking">, Group<f_Group>;
def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>;
def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<clang_ignored_f_Group>;
def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>;
@@ -358,7 +364,9 @@ def fsched_interblock : Flag<"-fsched-interblock">, Group<clang_ignored_f_Group>
def fshort_enums : Flag<"-fshort-enums">, Group<clang_ignored_f_Group>;
def freorder_blocks : Flag<"-freorder-blocks">, Group<clang_ignored_f_Group>;
def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>;
+def fshow_overloads_EQ : Joined<"-fshow-overloads=">, Group<f_Group>;
def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
+def fspell_checking : Flag<"-fspell-checking">, Group<f_Group>;
def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>;
def fsigned_char : Flag<"-fsigned-char">, Group<f_Group>;
def fstack_protector_all : Flag<"-fstack-protector-all">, Group<f_Group>;
@@ -381,6 +389,8 @@ def funwind_tables : Flag<"-funwind-tables">, Group<f_Group>;
def fuse_cxa_atexit : Flag<"-fuse-cxa-atexit">, Group<f_Group>;
def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>;
def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>;
+def fvisibility_inlines_hidden : Flag<"-fvisibility-inlines-hidden">, Group<f_Group>;
+def fwrapv : Flag<"-fwrapv">, Group<f_Group>;
def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>;
def fzero_initialized_in_bss : Flag<"-fzero-initialized-in-bss">, Group<f_Group>;
def ffunction_sections: Flag <"-ffunction-sections">, Group<f_Group>;
@@ -427,6 +437,7 @@ def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>;
def mfpu_EQ : Joined<"-mfpu=">, Group<m_Group>;
def mhard_float : Flag<"-mhard-float">, Group<m_Group>;
def miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>, Flags<[DriverOption]>;
+def mios_version_min_EQ : Joined<"-mios-version-min=">, Alias<miphoneos_version_min_EQ>;
def mkernel : Flag<"-mkernel">, Group<m_Group>;
def mllvm : Separate<"-mllvm">;
def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>, Flags<[DriverOption]>;
@@ -453,6 +464,8 @@ def mno_thumb : Flag<"-mno-thumb">, Group<m_Group>;
def marm : Flag<"-marm">, Alias<mno_thumb>;
def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Group<m_Group>;
+def mno_omit_leaf_frame_pointer : Flag<"-mno-omit-leaf-frame-pointer">, Group<f_Group>;
+def momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">, Group<f_Group>;
def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
def mrelax_all : Flag<"-mrelax-all">, Group<m_Group>;
@@ -585,7 +598,7 @@ def y : Joined<"-y">;
// options.
def _CLASSPATH_EQ : Joined<"--CLASSPATH=">, Alias<fclasspath_EQ>;
-def _CLASSPATH : Separate<"--CLASSPATH">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
+def _CLASSPATH : Separate<"--CLASSPATH">, Alias<fclasspath_EQ>;
def _all_warnings : Flag<"--all-warnings">, Alias<Wall>;
def _analyze_auto : Flag<"--analyze-auto">, Flags<[DriverOption]>;
def _analyzer_no_default_checks : Flag<"--analyzer-no-default-checks">, Flags<[DriverOption]>;
@@ -594,80 +607,80 @@ def _analyze : Flag<"--analyze">, Flags<[DriverOption]>,
HelpText<"Run the static analyzer">;
def _ansi : Flag<"--ansi">, Alias<ansi>;
def _assemble : Flag<"--assemble">, Alias<S>;
-def _assert_EQ : Joined<"--assert=">, Alias<A>, Flags<[RenderSeparate]>;
+def _assert_EQ : Joined<"--assert=">, Alias<A>;
def _assert : Separate<"--assert">, Alias<A>;
def _bootclasspath_EQ : Joined<"--bootclasspath=">, Alias<fbootclasspath_EQ>;
-def _bootclasspath : Separate<"--bootclasspath">, Alias<fbootclasspath_EQ>, Flags<[RenderJoined]>;
+def _bootclasspath : Separate<"--bootclasspath">, Alias<fbootclasspath_EQ>;
def _classpath_EQ : Joined<"--classpath=">, Alias<fclasspath_EQ>;
-def _classpath : Separate<"--classpath">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
-def _combine : Flag<"--combine">, Alias<combine>, Flags<[Unsupported]>;
+def _classpath : Separate<"--classpath">, Alias<fclasspath_EQ>;
+def _combine : Flag<"--combine">, Alias<combine>;
def _comments_in_macros : Flag<"--comments-in-macros">, Alias<CC>;
def _comments : Flag<"--comments">, Alias<C>;
def _compile : Flag<"--compile">, Alias<c>;
def _constant_cfstrings : Flag<"--constant-cfstrings">;
def _coverage : Flag<"--coverage">, Alias<coverage>;
-def _debug_EQ : Joined<"--debug=">, Alias<g_Flag>, Flags<[Unsupported]>;
-def _debug : Flag<"--debug">, Alias<g_Flag>, Flags<[Unsupported]>;
+def _debug_EQ : Joined<"--debug=">, Alias<g_Flag>;
+def _debug : Flag<"--debug">, Alias<g_Flag>;
def _define_macro_EQ : Joined<"--define-macro=">, Alias<D>;
-def _define_macro : Separate<"--define-macro">, Alias<D>, Flags<[RenderJoined]>;
+def _define_macro : Separate<"--define-macro">, Alias<D>;
def _dependencies : Flag<"--dependencies">, Alias<M>;
def _encoding_EQ : Joined<"--encoding=">, Alias<fencoding_EQ>;
-def _encoding : Separate<"--encoding">, Alias<fencoding_EQ>, Flags<[RenderJoined]>;
+def _encoding : Separate<"--encoding">, Alias<fencoding_EQ>;
def _entry : Flag<"--entry">, Alias<e>;
def _extdirs_EQ : Joined<"--extdirs=">, Alias<fextdirs_EQ>;
-def _extdirs : Separate<"--extdirs">, Alias<fextdirs_EQ>, Flags<[RenderJoined]>;
+def _extdirs : Separate<"--extdirs">, Alias<fextdirs_EQ>;
def _extra_warnings : Flag<"--extra-warnings">, Alias<W_Joined>;
-def _for_linker_EQ : Joined<"--for-linker=">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput, RenderSeparate]>;
-def _for_linker : Separate<"--for-linker">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput]>;
-def _force_link_EQ : Joined<"--force-link=">, Alias<u>, Flags<[RenderSeparate]>;
+def _for_linker_EQ : Joined<"--for-linker=">, Alias<Xlinker>;
+def _for_linker : Separate<"--for-linker">, Alias<Xlinker>;
+def _force_link_EQ : Joined<"--force-link=">, Alias<u>;
def _force_link : Separate<"--force-link">, Alias<u>;
def _help_hidden : Flag<"--help-hidden">;
def _help : Flag<"--help">,
HelpText<"Display available options">;
-def _imacros_EQ : Joined<"--imacros=">, Alias<imacros>, Flags<[RenderSeparate]>;
+def _imacros_EQ : Joined<"--imacros=">, Alias<imacros>;
def _imacros : Separate<"--imacros">, Alias<imacros>;
def _include_barrier : Flag<"--include-barrier">, Alias<I_>;
-def _include_directory_after_EQ : Joined<"--include-directory-after=">, Alias<idirafter>, Flags<[RenderSeparate]>;
+def _include_directory_after_EQ : Joined<"--include-directory-after=">, Alias<idirafter>;
def _include_directory_after : Separate<"--include-directory-after">, Alias<idirafter>;
def _include_directory_EQ : Joined<"--include-directory=">, Alias<I>;
-def _include_directory : Separate<"--include-directory">, Alias<I>, Flags<[RenderJoined]>;
-def _include_prefix_EQ : Joined<"--include-prefix=">, Alias<iprefix>, Flags<[RenderSeparate]>;
+def _include_directory : Separate<"--include-directory">, Alias<I>;
+def _include_prefix_EQ : Joined<"--include-prefix=">, Alias<iprefix>;
def _include_prefix : Separate<"--include-prefix">, Alias<iprefix>;
-def _include_with_prefix_after_EQ : Joined<"--include-with-prefix-after=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
+def _include_with_prefix_after_EQ : Joined<"--include-with-prefix-after=">, Alias<iwithprefix>;
def _include_with_prefix_after : Separate<"--include-with-prefix-after">, Alias<iwithprefix>;
-def _include_with_prefix_before_EQ : Joined<"--include-with-prefix-before=">, Alias<iwithprefixbefore>, Flags<[RenderSeparate]>;
+def _include_with_prefix_before_EQ : Joined<"--include-with-prefix-before=">, Alias<iwithprefixbefore>;
def _include_with_prefix_before : Separate<"--include-with-prefix-before">, Alias<iwithprefixbefore>;
-def _include_with_prefix_EQ : Joined<"--include-with-prefix=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
+def _include_with_prefix_EQ : Joined<"--include-with-prefix=">, Alias<iwithprefix>;
def _include_with_prefix : Separate<"--include-with-prefix">, Alias<iwithprefix>;
-def _include_EQ : Joined<"--include=">, Alias<include_>, Flags<[RenderSeparate]>;
+def _include_EQ : Joined<"--include=">, Alias<include_>;
def _include : Separate<"--include">, Alias<include_>;
-def _language_EQ : Joined<"--language=">, Alias<x>, Flags<[RenderSeparate]>;
+def _language_EQ : Joined<"--language=">, Alias<x>;
def _language : Separate<"--language">, Alias<x>;
-def _library_directory_EQ : Joined<"--library-directory=">, Alias<L>, Flags<[RenderSeparate]>;
+def _library_directory_EQ : Joined<"--library-directory=">, Alias<L>;
def _library_directory : Separate<"--library-directory">, Alias<L>;
-def _machine__EQ : Joined<"--machine-=">, Alias<m_Joined>, Flags<[Unsupported]>;
-def _machine_ : Joined<"--machine-">, Alias<m_Joined>, Flags<[Unsupported]>;
+def _machine__EQ : Joined<"--machine-=">, Alias<m_Joined>;
+def _machine_ : Joined<"--machine-">, Alias<m_Joined>;
def _machine_EQ : Joined<"--machine=">, Alias<m_Joined>;
-def _machine : Separate<"--machine">, Alias<m_Joined>, Flags<[RenderJoined]>;
+def _machine : Separate<"--machine">, Alias<m_Joined>;
def _no_integrated_cpp : Flag<"--no-integrated-cpp">, Alias<no_integrated_cpp>;
def _no_line_commands : Flag<"--no-line-commands">, Alias<P>;
def _no_standard_includes : Flag<"--no-standard-includes">, Alias<nostdinc>;
def _no_standard_libraries : Flag<"--no-standard-libraries">, Alias<nostdlib>;
def _no_undefined : Flag<"--no-undefined">, Flags<[LinkerInput]>;
def _no_warnings : Flag<"--no-warnings">, Alias<w>;
-def _optimize_EQ : Joined<"--optimize=">, Alias<O>, Flags<[Unsupported]>;
-def _optimize : Flag<"--optimize">, Alias<O>, Flags<[Unsupported]>;
+def _optimize_EQ : Joined<"--optimize=">, Alias<O>;
+def _optimize : Flag<"--optimize">, Alias<O>;
def _output_class_directory_EQ : Joined<"--output-class-directory=">, Alias<foutput_class_dir_EQ>;
-def _output_class_directory : Separate<"--output-class-directory">, Alias<foutput_class_dir_EQ>, Flags<[RenderJoined]>;
-def _output_EQ : Joined<"--output=">, Alias<o>, Flags<[RenderSeparate]>;
+def _output_class_directory : Separate<"--output-class-directory">, Alias<foutput_class_dir_EQ>;
+def _output_EQ : Joined<"--output=">, Alias<o>;
def _output : Separate<"--output">, Alias<o>;
def _param : Separate<"--param">;
-def _param_EQ : Joined<"--param=">, Alias<_param>, Flags<[RenderSeparate]>;
+def _param_EQ : Joined<"--param=">, Alias<_param>;
def _pass_exit_codes : Flag<"--pass-exit-codes">, Alias<pass_exit_codes>;
def _pedantic_errors : Flag<"--pedantic-errors">, Alias<pedantic_errors>;
def _pedantic : Flag<"--pedantic">, Alias<pedantic>;
-def _pipe : Flag<"--pipe">, Alias<pipe>, Flags<[DriverOption]>;
-def _prefix_EQ : Joined<"--prefix=">, Alias<B>, Flags<[RenderSeparate]>;
+def _pipe : Flag<"--pipe">, Alias<pipe>;
+def _prefix_EQ : Joined<"--prefix=">, Alias<B>;
def _prefix : Separate<"--prefix">, Alias<B>;
def _preprocess : Flag<"--preprocess">, Alias<E>;
def _print_diagnostic_categories : Flag<"--print-diagnostic-categories">;
@@ -686,30 +699,33 @@ def _profile : Flag<"--profile">, Alias<p>;
def _relocatable_pch : Flag<"--relocatable-pch">,
HelpText<"Build a relocatable precompiled header">;
def _resource_EQ : Joined<"--resource=">, Alias<fcompile_resource_EQ>;
-def _resource : Separate<"--resource">, Alias<fcompile_resource_EQ>, Flags<[RenderJoined]>;
+def _resource : Separate<"--resource">, Alias<fcompile_resource_EQ>;
def _save_temps : Flag<"--save-temps">, Alias<save_temps>;
def _shared : Flag<"--shared">, Alias<shared>;
def _signed_char : Flag<"--signed-char">, Alias<fsigned_char>;
-def _specs_EQ : Joined<"--specs=">, Alias<specs_EQ>, Flags<[Unsupported]>;
-def _specs : Separate<"--specs">, Alias<specs_EQ>, Flags<[RenderJoined, Unsupported]>;
+def _specs_EQ : Joined<"--specs=">, Alias<specs_EQ>;
+def _specs : Separate<"--specs">, Alias<specs_EQ>;
def _static : Flag<"--static">, Alias<static>;
def _std_EQ : Joined<"--std=">, Alias<std_EQ>;
-def _std : Separate<"--std">, Alias<std_EQ>, Flags<[RenderJoined]>;
+def _std : Separate<"--std">, Alias<std_EQ>;
def _sysroot_EQ : Joined<"--sysroot=">;
-def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>, Flags<[RenderJoined]>;
+def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>;
def _target_help : Flag<"--target-help">;
def _trace_includes : Flag<"--trace-includes">, Alias<H>;
def _traditional_cpp : Flag<"--traditional-cpp">, Alias<traditional_cpp>;
def _traditional : Flag<"--traditional">, Alias<traditional>;
def _trigraphs : Flag<"--trigraphs">, Alias<trigraphs>;
def _undefine_macro_EQ : Joined<"--undefine-macro=">, Alias<U>;
-def _undefine_macro : Separate<"--undefine-macro">, Alias<U>, Flags<[RenderJoined]>;
+def _undefine_macro : Separate<"--undefine-macro">, Alias<U>;
def _unsigned_char : Flag<"--unsigned-char">, Alias<funsigned_char>;
def _user_dependencies : Flag<"--user-dependencies">, Alias<MM>;
def _verbose : Flag<"--verbose">, Alias<v>;
def _version : Flag<"--version">;
-def _warn__EQ : Joined<"--warn-=">, Alias<W_Joined>, Flags<[Unsupported]>;
-def _warn_ : Joined<"--warn-">, Alias<W_Joined>, Flags<[Unsupported]>;
+def _warn__EQ : Joined<"--warn-=">, Alias<W_Joined>;
+def _warn_ : Joined<"--warn-">, Alias<W_Joined>;
def _write_dependencies : Flag<"--write-dependencies">, Alias<MD>;
def _write_user_dependencies : Flag<"--write-user-dependencies">, Alias<MMD>;
-def _ : Joined<"--">, Alias<f>, Flags<[Unsupported]>;
+def _ : Joined<"--">, Flags<[Unsupported]>;
+
+// Special internal option to handle -Xlinker --no-demangle.
+def Z_Xlinker__no_demangle : Flag<"-Z-Xlinker-no-demangle">, Flags<[Unsupported]>;
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 1a8ae7749143..2cec22a09d8b 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -70,11 +70,14 @@ public:
// Tool access.
/// TranslateArgs - Create a new derived argument list for any argument
- /// translations this ToolChain may wish to perform.
+ /// translations this ToolChain may wish to perform, or 0 if no tool chain
+ /// specific translations are needed.
///
/// \param BoundArch - The bound architecture name, or 0.
- virtual DerivedArgList *TranslateArgs(InputArgList &Args,
- const char *BoundArch) const = 0;
+ virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args,
+ const char *BoundArch) const {
+ return 0;
+ }
/// SelectTool - Choose a tool to use to handle the action \arg JA.
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const = 0;
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index 61a5043b34fc..d3a3d29fbc0f 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -67,15 +67,21 @@ TYPE("f95", PP_Fortran, INVALID, 0, "u")
TYPE("f95-cpp-input", Fortran, PP_Fortran, 0, "u")
TYPE("java", Java, INVALID, 0, "u")
+// LLVM IR/LTO types. We define separate types for IR and LTO because LTO
+// outputs should use the standard suffixes.
+TYPE("ir", LLVM_IR, INVALID, "ll", "")
+TYPE("ir", LLVM_BC, INVALID, "bc", "")
+TYPE("lto-ir", LTO_IR, INVALID, "s", "")
+TYPE("lto-bc", LTO_BC, INVALID, "o", "")
+
// Misc.
TYPE("ast", AST, INVALID, "ast", "u")
-TYPE("llvm-asm", LLVMAsm, INVALID, "s", "")
-TYPE("llvm-bc", LLVMBC, INVALID, "o", "")
TYPE("plist", Plist, INVALID, "plist", "")
TYPE("rewritten-objc", RewrittenObjC,INVALID, "cpp", "")
TYPE("precompiled-header", PCH, INVALID, "gch", "A")
TYPE("object", Object, INVALID, "o", "")
TYPE("treelang", Treelang, INVALID, 0, "u")
TYPE("image", Image, INVALID, "out", "")
+TYPE("dSYM", dSYM, INVALID, "dSYM", "A")
TYPE("dependencies", Dependencies, INVALID, "d", "")
TYPE("none", Nothing, INVALID, 0, "u")
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index d93323016fe3..9187529833ac 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -59,6 +59,10 @@ namespace types {
/// isAcceptedByClang - Can clang handle this input type.
bool isAcceptedByClang(ID Id);
+ /// isOnlyAcceptedByClang - Is clang the only compiler that can handle this
+ /// input type.
+ bool isOnlyAcceptedByClang(ID Id);
+
/// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
bool isCXX(ID Id);
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 9163a208de2e..5718979ba1db 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -29,6 +29,7 @@ class CodeGenOptions;
class Diagnostic;
class FileManager;
class LangOptions;
+class PCHReader;
class Preprocessor;
class TargetOptions;
@@ -57,25 +58,12 @@ ASTConsumer *CreateASTViewer();
// to stderr; this is intended for debugging.
ASTConsumer *CreateDeclContextPrinter();
-// ObjC rewriter: attempts tp rewrite ObjC constructs into pure C code.
-// This is considered experimental, and only works with Apple's ObjC runtime.
-ASTConsumer *CreateObjCRewriter(const std::string &InFile,
- llvm::raw_ostream *OS,
- Diagnostic &Diags,
- const LangOptions &LOpts,
- bool SilenceRewriteMacroWarning);
-
-/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
-/// HTML with syntax highlighting suitable for viewing in a web-browser.
-ASTConsumer *CreateHTMLPrinter(llvm::raw_ostream *OS, Preprocessor &PP,
- bool SyntaxHighlight = true,
- bool HighlightMacros = true);
-
// PCH generator: generates a precompiled header file; this file can be used
// later with the PCHReader (clang -cc1 option -include-pch) to speed up compile
// times.
ASTConsumer *CreatePCHGenerator(const Preprocessor &PP,
llvm::raw_ostream *OS,
+ const PCHReader *Chain,
const char *isysroot = 0);
// Inheritance viewer: for C++ code, creates a graph of the inheritance
diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalyzerOptions.h
index 2cbdf368a893..ab4aed96d864 100644
--- a/include/clang/Frontend/AnalysisConsumer.h
+++ b/include/clang/Frontend/AnalyzerOptions.h
@@ -1,4 +1,4 @@
-//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
+//===--- AnalyzerOptions.h - Analysis Engine Options ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
//
-// This header contains the functions necessary for a front-end to run various
-// analyses.
+// This header contains the structures necessary for a front-end to specify
+// various analyses.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H
-#define LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H
+#ifndef LLVM_CLANG_FRONTEND_ANALYZEROPTIONS_H
+#define LLVM_CLANG_FRONTEND_ANALYZEROPTIONS_H
#include <string>
#include <vector>
@@ -72,6 +72,7 @@ public:
unsigned VisualizeEGUbi : 1;
unsigned EnableExperimentalChecks : 1;
unsigned EnableExperimentalInternalChecks : 1;
+ unsigned EnableIdempotentOperationChecker : 1;
unsigned InlineCall : 1;
public:
@@ -92,13 +93,6 @@ public:
}
};
-/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
-/// analysis passes. (The set of analyses run is controlled by command-line
-/// options.)
-ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp,
- const std::string &output,
- const AnalyzerOptions& Opts);
-
}
#endif
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 6241230ffb45..2918f4e9d3cb 100644
--- a/include/clang/CodeGen/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
-#define LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
+#ifndef LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
+#define LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
#include <string>
@@ -39,7 +39,7 @@ public:
unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker
/// aliases to base ctors when possible.
unsigned DataSections : 1; /// Set when -fdata-sections is enabled
- unsigned DebugInfo : 1; /// Should generate deubg info (-g).
+ unsigned DebugInfo : 1; /// Should generate debug info (-g).
unsigned DisableFPElim : 1; /// Set when -fomit-frame-pointer is enabled.
unsigned DisableLLVMOpts : 1; /// Don't run any optimizations, for use in
/// getting .bc files that correspond to the
@@ -47,14 +47,18 @@ public:
/// done.
unsigned DisableRedZone : 1; /// Set when -mno-red-zone is enabled.
unsigned FunctionSections : 1; /// Set when -ffunction-sections is enabled
+ unsigned InstrumentFunctions : 1; /// Set when -finstrument-functions is enabled
unsigned MergeAllConstants : 1; /// Merge identical constants.
unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use.
+ unsigned OmitLeafFramePointer : 1; /// Set when -momit-leaf-frame-pointer is
+ /// enabled.
unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
unsigned OptimizeSize : 1; /// If -Os is specified.
unsigned RelaxAll : 1; /// Relax all machine code instructions.
+ unsigned SimplifyLibCalls : 1; /// Set when -fbuiltin is enabled.
unsigned SoftFloat : 1; /// -soft-float.
unsigned TimePasses : 1; /// Set when -ftime-report is enabled.
unsigned UnitAtATime : 1; /// Unused. For mirroring GCC optimization
@@ -63,6 +67,9 @@ public:
unsigned UnwindTables : 1; /// Emit unwind tables.
unsigned VerifyModule : 1; /// Control whether the module should be run
/// through the LLVM Verifier.
+ unsigned EmitDeclMetadata : 1; /// Emit special metadata indicating what Decl*
+ /// various IR entities came from. Only useful
+ /// when running CodeGen as a subroutine.
/// The code model to use (-mcmodel).
std::string CodeModel;
@@ -107,15 +114,18 @@ public:
NoImplicitFloat = 0;
NoZeroInitializedInBSS = 0;
ObjCDispatchMethod = Legacy;
+ OmitLeafFramePointer = 0;
OptimizationLevel = 0;
OptimizeSize = 0;
RelaxAll = 0;
+ SimplifyLibCalls = 1;
SoftFloat = 0;
TimePasses = 0;
UnitAtATime = 1;
UnrollLoops = 0;
UnwindTables = 0;
VerifyModule = 1;
+ EmitDeclMetadata = 0;
Inlining = NoInlining;
RelocationModel = "pic";
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 06dc8004a652..54ce8bfe3ba0 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -34,6 +34,7 @@ class DiagnosticClient;
class ExternalASTSource;
class FileManager;
class FrontendAction;
+class PCHReader;
class Preprocessor;
class SourceManager;
class TargetInfo;
@@ -96,6 +97,9 @@ class CompilerInstance {
/// The list of active output files.
std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles;
+ /// The PCH reader. Not owned; the ASTContext owns this.
+ PCHReader *Reader;
+
void operator=(const CompilerInstance &); // DO NOT IMPLEMENT
CompilerInstance(const CompilerInstance&); // DO NOT IMPLEMENT
public:
@@ -507,6 +511,9 @@ public:
createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
Preprocessor &PP, ASTContext &Context);
+ /// Get the PCH reader, if any.
+ PCHReader *getPCHReader() { return Reader; }
+
/// Create a code completion consumer using the invocation; note that this
/// will cause the source manager to truncate the input source file at the
/// completion point.
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index f5a9053ceb64..d558ad391406 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -12,8 +12,8 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetOptions.h"
-#include "clang/CodeGen/CodeGenOptions.h"
-#include "clang/Frontend/AnalysisConsumer.h"
+#include "clang/Frontend/AnalyzerOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/FrontendOptions.h"
diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h
index 8eb66e57da92..516dc67b425d 100644
--- a/include/clang/Frontend/DiagnosticOptions.h
+++ b/include/clang/Frontend/DiagnosticOptions.h
@@ -10,6 +10,8 @@
#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H
#define LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H
+#include "clang/Basic/Diagnostic.h"
+
#include <string>
#include <vector>
@@ -33,6 +35,8 @@ public:
unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number,
/// 2 -> Full Name.
unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences.
+ unsigned ShowOverloads : 1; /// Overload candidates to show. Values from
+ /// Diagnostic::OverloadsShown
unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected
/// diagnostics, indicated by markers in the
/// input source file.
@@ -72,6 +76,7 @@ public:
PedanticErrors = 0;
ShowCarets = 1;
ShowColors = 0;
+ ShowOverloads = Diagnostic::Ovl_All;
ShowColumn = 1;
ShowFixits = 1;
ShowLocation = 1;
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 7b7db3785cf3..f6a68bf69e89 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -13,17 +13,40 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/OwningPtr.h"
#include <string>
+#include <vector>
+
+namespace llvm {
+ class raw_ostream;
+}
namespace clang {
-class ASTUnit;
class ASTConsumer;
-class CompilerInstance;
class ASTMergeAction;
+class ASTUnit;
+class CompilerInstance;
+
+enum InputKind {
+ IK_None,
+ IK_Asm,
+ IK_C,
+ IK_CXX,
+ IK_ObjC,
+ IK_ObjCXX,
+ IK_PreprocessedC,
+ IK_PreprocessedCXX,
+ IK_PreprocessedObjC,
+ IK_PreprocessedObjCXX,
+ IK_OpenCL,
+ IK_AST,
+ IK_LLVM_IR
+};
+
/// FrontendAction - Abstract base class for actions which can be performed by
/// the frontend.
class FrontendAction {
std::string CurrentFile;
+ InputKind CurrentFileKind;
llvm::OwningPtr<ASTUnit> CurrentASTUnit;
CompilerInstance *Instance;
friend class ASTMergeAction;
@@ -101,6 +124,11 @@ public:
return CurrentFile;
}
+ InputKind getCurrentFileKind() const {
+ assert(!CurrentFile.empty() && "No current file!");
+ return CurrentFileKind;
+ }
+
ASTUnit &getCurrentASTUnit() const {
assert(!CurrentASTUnit && "No current AST unit!");
return *CurrentASTUnit;
@@ -110,7 +138,7 @@ public:
return CurrentASTUnit.take();
}
- void setCurrentFile(llvm::StringRef Value, ASTUnit *AST = 0);
+ void setCurrentFile(llvm::StringRef Value, InputKind Kind, ASTUnit *AST = 0);
/// @}
/// @name Supported Modes
@@ -128,8 +156,11 @@ public:
/// hasPCHSupport - Does this action support use with PCH?
virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
- /// hasASTSupport - Does this action support use with AST files?
- virtual bool hasASTSupport() const { return !usesPreprocessorOnly(); }
+ /// hasASTFileSupport - Does this action support use with AST files?
+ virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
+
+ /// hasIRSupport - Does this action support use with IR files?
+ virtual bool hasIRSupport() const { return false; }
/// hasCodeCompletionSupport - Does this action support use with code
/// completion?
@@ -150,17 +181,18 @@ public:
/// \param Filename - The input filename, which will be made available to
/// clients via \see getCurrentFile().
///
- /// \param IsAST - Indicates whether this is an AST input. AST inputs require
- /// special handling, since the AST file itself contains several objects which
- /// would normally be owned by the CompilerInstance. When processing AST input
- /// files, these objects should generally not be initialized in the
- /// CompilerInstance -- they will automatically be shared with the AST file in
- /// between \see BeginSourceFile() and \see EndSourceFile().
+ /// \param InputKind - The type of input. Some input kinds are handled
+ /// specially, for example AST inputs, since the AST file itself contains
+ /// several objects which would normally be owned by the
+ /// CompilerInstance. When processing AST input files, these objects should
+ /// generally not be initialized in the CompilerInstance -- they will
+ /// automatically be shared with the AST file in between \see
+ /// BeginSourceFile() and \see EndSourceFile().
///
/// \return True on success; the compilation of this file should be aborted
/// and neither Execute nor EndSourceFile should be called.
bool BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename,
- bool IsAST = false);
+ InputKind Kind);
/// Execute - Set the source managers main input file, and run the action.
void Execute();
@@ -175,6 +207,7 @@ public:
/// ASTFrontendAction - Abstract base class to use for AST consumer based
/// frontend actions.
class ASTFrontendAction : public FrontendAction {
+protected:
/// ExecuteAction - Implement the ExecuteAction interface by running Sema on
/// the already initialized AST consumer.
///
@@ -186,6 +219,16 @@ public:
virtual bool usesPreprocessorOnly() const { return false; }
};
+class PluginASTAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile) = 0;
+
+public:
+ virtual bool ParseArgs(const std::vector<std::string>& arg) = 0;
+ virtual void PrintHelp(llvm::raw_ostream&) = 0;
+};
+
/// PreprocessorFrontendAction - Abstract base class to use for preprocessor
/// based frontend actions.
class PreprocessorFrontendAction : public FrontendAction {
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index cee1c1d2be77..26262cfa9522 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -15,8 +15,6 @@
#include <vector>
namespace clang {
-class FixItRewriter;
-class FixItPathRewriter;
//===----------------------------------------------------------------------===//
// Custom Consumer Actions
@@ -38,12 +36,6 @@ public:
// AST Consumer Actions
//===----------------------------------------------------------------------===//
-class AnalysisAction : public ASTFrontendAction {
-protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile);
-};
-
class ASTPrintAction : public ASTFrontendAction {
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
@@ -74,26 +66,6 @@ protected:
llvm::StringRef InFile);
};
-class FixItAction : public ASTFrontendAction {
-protected:
- llvm::OwningPtr<FixItRewriter> Rewriter;
- llvm::OwningPtr<FixItPathRewriter> PathRewriter;
-
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile);
-
- virtual bool BeginSourceFileAction(CompilerInstance &CI,
- llvm::StringRef Filename);
-
- virtual void EndSourceFileAction();
-
- virtual bool hasASTSupport() const { return false; }
-
-public:
- FixItAction();
- ~FixItAction();
-};
-
class GeneratePCHAction : public ASTFrontendAction {
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
@@ -101,13 +73,7 @@ protected:
virtual bool usesCompleteTranslationUnit() { return false; }
- virtual bool hasASTSupport() const { return false; }
-};
-
-class HTMLPrintAction : public ASTFrontendAction {
-protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile);
+ virtual bool hasASTFileSupport() const { return false; }
};
class InheritanceViewAction : public ASTFrontendAction {
@@ -116,12 +82,6 @@ protected:
llvm::StringRef InFile);
};
-class RewriteObjCAction : public ASTFrontendAction {
-protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile);
-};
-
class SyntaxOnlyAction : public ASTFrontendAction {
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
@@ -170,7 +130,7 @@ public:
virtual bool usesPreprocessorOnly() const;
virtual bool usesCompleteTranslationUnit();
virtual bool hasPCHSupport() const;
- virtual bool hasASTSupport() const;
+ virtual bool hasASTFileSupport() const;
virtual bool hasCodeCompletionSupport() const;
};
@@ -215,16 +175,6 @@ protected:
virtual bool hasPCHSupport() const { return true; }
};
-class RewriteMacrosAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction();
-};
-
-class RewriteTestAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction();
-};
-
} // end namespace clang
#endif
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index c43e68000952..4010ea6dd7dc 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
#include "clang/Frontend/CommandLineSourceLoc.h"
+#include "clang/Frontend/FrontendAction.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
@@ -55,27 +56,15 @@ namespace frontend {
/// FrontendOptions - Options for controlling the behavior of the frontend.
class FrontendOptions {
public:
- enum InputKind {
- IK_None,
- IK_Asm,
- IK_C,
- IK_CXX,
- IK_ObjC,
- IK_ObjCXX,
- IK_PreprocessedC,
- IK_PreprocessedCXX,
- IK_PreprocessedObjC,
- IK_PreprocessedObjCXX,
- IK_OpenCL,
- IK_AST
- };
-
unsigned DebugCodeCompletionPrinter : 1; ///< Use the debug printer for code
/// completion results.
unsigned DisableFree : 1; ///< Disable memory freeing on exit.
unsigned RelocatablePCH : 1; ///< When generating PCH files,
/// instruct the PCH writer to create
/// relocatable PCH files.
+ unsigned ChainedPCH : 1; ///< When generating PCH files,
+ /// instruct the PCH writer to create
+ /// chained PCH files.
unsigned ShowHelp : 1; ///< Show the -help text.
unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
/// results.
@@ -108,6 +97,9 @@ public:
/// The name of the action to run when using a plugin action.
std::string ActionName;
+ /// Arg to pass to the plugin
+ std::vector<std::string> PluginArgs;
+
/// The list of plugins to load.
std::vector<std::string> Plugins;
@@ -125,6 +117,7 @@ public:
ProgramAction = frontend::ParseSyntaxOnly;
ActionName = "";
RelocatablePCH = 0;
+ ChainedPCH = 0;
ShowHelp = 0;
ShowMacrosInCodeCompletion = 0;
ShowCodePatternsInCodeCompletion = 0;
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
index 8341492cfd23..ec925adb0186 100644
--- a/include/clang/Frontend/FrontendPluginRegistry.h
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -16,7 +16,7 @@
namespace clang {
/// The frontend plugin registry.
-typedef llvm::Registry<FrontendAction> FrontendPluginRegistry;
+typedef llvm::Registry<PluginASTAction> FrontendPluginRegistry;
} // end namespace clang
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 2493cfd47d1e..27a2b7d0b951 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -30,10 +30,10 @@ namespace clang {
/// designed for the previous version could not support reading
/// the new version), this number should be increased.
///
- /// Version 3 of PCH files also requires that the version control branch and
+ /// Version 4 of PCH files also requires that the version control branch and
/// revision match exactly, since there is no backward compatibility of
/// PCH files at this time.
- const unsigned VERSION_MAJOR = 3;
+ const unsigned VERSION_MAJOR = 4;
/// \brief PCH minor version number supported by this version of
/// Clang.
@@ -47,7 +47,7 @@ namespace clang {
/// \brief An ID number that refers to a declaration in a PCH file.
///
- /// The ID numbers of types are consecutive (in order of
+ /// The ID numbers of declarations are consecutive (in order of
/// discovery) and start at 2. 0 is reserved for NULL, and 1 is
/// reserved for the translation unit declaration.
typedef uint32_t DeclID;
@@ -226,7 +226,18 @@ namespace clang {
/// \brief Record code for the table of offsets to macro definition
/// entries in the preprocessing record.
- MACRO_DEFINITION_OFFSETS = 23
+ MACRO_DEFINITION_OFFSETS = 23,
+
+ /// \brief Record code for the array of VTable uses.
+ VTABLE_USES = 24,
+
+ /// \brief Record code for the array of dynamic classes.
+ DYNAMIC_CLASSES = 25,
+
+ /// \brief Record code for the chained PCH metadata, including the
+ /// PCH version and the name of the PCH this is chained to.
+ CHAINED_METADATA = 26
+
};
/// \brief Record types used within a source manager block.
@@ -417,7 +428,17 @@ namespace clang {
/// \brief An InjectedClassNameType record.
TYPE_INJECTED_CLASS_NAME = 27,
/// \brief An ObjCObjectType record.
- TYPE_OBJC_OBJECT = 28
+ TYPE_OBJC_OBJECT = 28,
+ /// \brief An TemplateTypeParmType record.
+ TYPE_TEMPLATE_TYPE_PARM = 29,
+ /// \brief An TemplateSpecializationType record.
+ TYPE_TEMPLATE_SPECIALIZATION = 30,
+ /// \brief A DependentNameType record.
+ TYPE_DEPENDENT_NAME = 31,
+ /// \brief A DependentTemplateSpecializationType record.
+ TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
+ /// \brief A DependentSizedArrayType record.
+ TYPE_DEPENDENT_SIZED_ARRAY = 33
};
/// \brief The type IDs for special types constructed by semantic
@@ -457,7 +478,9 @@ namespace clang {
/// \brief Objective-C "SEL" redefinition type
SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 14,
/// \brief NSConstantString type
- SPECIAL_TYPE_NS_CONSTANT_STRING = 15
+ SPECIAL_TYPE_NS_CONSTANT_STRING = 15,
+ /// \brief Whether __[u]int128_t identifier is installed.
+ SPECIAL_TYPE_INT128_INSTALLED = 16
};
/// \brief Record codes for each kind of declaration.
@@ -562,12 +585,13 @@ namespace clang {
DECL_CXX_DESTRUCTOR,
/// \brief A CXXConversionDecl record.
DECL_CXX_CONVERSION,
+ /// \brief An AccessSpecDecl record.
+ DECL_ACCESS_SPEC,
// FIXME: Implement serialization for these decl types. This just
// allocates the order in which
DECL_FRIEND,
DECL_FRIEND_TEMPLATE,
- DECL_TEMPLATE,
DECL_CLASS_TEMPLATE,
DECL_CLASS_TEMPLATE_SPECIALIZATION,
DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
@@ -641,6 +665,8 @@ namespace clang {
EXPR_CHARACTER_LITERAL,
/// \brief A ParenExpr record.
EXPR_PAREN,
+ /// \brief A ParenListExpr record.
+ EXPR_PAREN_LIST,
/// \brief A UnaryOperator record.
EXPR_UNARY_OPERATOR,
/// \brief An OffsetOfExpr record.
@@ -736,6 +762,8 @@ namespace clang {
EXPR_CXX_MEMBER_CALL,
/// \brief A CXXConstructExpr record.
EXPR_CXX_CONSTRUCT,
+ /// \brief A CXXTemporaryObjectExpr record.
+ EXPR_CXX_TEMPORARY_OBJECT,
// \brief A CXXStaticCastExpr record.
EXPR_CXX_STATIC_CAST,
// \brief A CXXDynamicCastExpr record.
@@ -755,11 +783,22 @@ namespace clang {
EXPR_CXX_THROW, // CXXThrowExpr
EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr
EXPR_CXX_BIND_TEMPORARY, // CXXBindTemporaryExpr
- //
- EXPR_CXX_ZERO_INIT_VALUE, // CXXZeroInitValueExpr
+ EXPR_CXX_BIND_REFERENCE, // CXXBindReferenceExpr
+
+ EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr
EXPR_CXX_NEW, // CXXNewExpr
+ EXPR_CXX_DELETE, // CXXDeleteExpr
+ EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr
+
+ EXPR_CXX_EXPR_WITH_TEMPORARIES, // CXXExprWithTemporaries
- EXPR_CXX_EXPR_WITH_TEMPORARIES // CXXExprWithTemporaries
+ EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr
+ EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr
+ EXPR_CXX_UNRESOLVED_CONSTRUCT, // CXXUnresolvedConstructExpr
+ EXPR_CXX_UNRESOLVED_MEMBER, // UnresolvedMemberExpr
+ EXPR_CXX_UNRESOLVED_LOOKUP, // UnresolvedLookupExpr
+
+ EXPR_CXX_UNARY_TYPE_TRAIT // UnaryTypeTraitExpr
};
/// \brief The kinds of designators that can occur in a
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index e144738236ea..38402732a342 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -321,7 +321,7 @@ private:
/// file.
llvm::SmallVector<uint64_t, 16> TentativeDefinitions;
- /// \brief The set of tentative definitions stored in the the PCH
+ /// \brief The set of unused static functions stored in the the PCH
/// file.
llvm::SmallVector<uint64_t, 16> UnusedStaticFuncs;
@@ -333,6 +333,12 @@ private:
/// PCH file.
llvm::SmallVector<uint64_t, 4> ExtVectorDecls;
+ /// \brief The set of VTable uses of CXXRecordDecls stored in the PCH file.
+ llvm::SmallVector<uint64_t, 64> VTableUses;
+
+ /// \brief The set of dynamic CXXRecord declarations stored in the PCH file.
+ llvm::SmallVector<uint64_t, 16> DynamicClasses;
+
/// \brief The set of Objective-C category definitions stored in the
/// the PCH file.
llvm::SmallVector<uint64_t, 4> ObjCCategoryImpls;
@@ -447,7 +453,35 @@ private:
/// "Interesting" declarations are those that have data that may
/// need to be emitted, such as inline function definitions or
/// Objective-C protocols.
- llvm::SmallVector<Decl *, 16> InterestingDecls;
+ std::deque<Decl *> InterestingDecls;
+
+ /// \brief When reading a Stmt tree, Stmt operands are placed in this stack.
+ llvm::SmallVector<Stmt *, 16> StmtStack;
+
+ /// \brief What kind of records we are reading.
+ enum ReadingKind {
+ Read_Decl, Read_Type, Read_Stmt
+ };
+
+ /// \brief What kind of records we are reading.
+ ReadingKind ReadingKind;
+
+ /// \brief RAII object to change the reading kind.
+ class ReadingKindTracker {
+ PCHReader &Reader;
+ enum ReadingKind PrevKind;
+
+ ReadingKindTracker(const ReadingKindTracker&); // do not implement
+ ReadingKindTracker &operator=(const ReadingKindTracker&);// do not implement
+
+ public:
+ ReadingKindTracker(enum ReadingKind newKind, PCHReader &reader)
+ : Reader(reader), PrevKind(Reader.ReadingKind) {
+ Reader.ReadingKind = newKind;
+ }
+
+ ~ReadingKindTracker() { Reader.ReadingKind = PrevKind; }
+ };
/// \brief The file ID for the predefines buffer in the PCH file.
FileID PCHPredefinesBufferID;
@@ -469,6 +503,9 @@ private:
/// predefines buffer may contain additional definitions.
std::string SuggestedPredefines;
+ /// \brief Reads a statement from the specified cursor.
+ Stmt *ReadStmtFromStream(llvm::BitstreamCursor &Cursor);
+
void MaybeAddSystemRootToFilename(std::string &Filename);
PCHReadResult ReadPCHBlock();
@@ -482,6 +519,8 @@ private:
void LoadedDecl(unsigned Index, Decl *D);
Decl *ReadDeclRecord(uint64_t Offset, unsigned Index);
+ void PassInterestingDeclsToConsumer();
+
/// \brief Produce an error diagnostic and return true.
///
/// This routine should only be used for fatal errors that have to
@@ -544,7 +583,7 @@ public:
void InitializeContext(ASTContext &Context);
/// \brief Retrieve the name of the PCH file
- const std::string &getFileName() { return FileName; }
+ const std::string &getFileName() const { return FileName; }
/// \brief Retrieve the name of the original source file name
const std::string &getOriginalSourceFile() { return OriginalFileName; }
@@ -569,30 +608,45 @@ public:
GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const RecordData &Record, unsigned &Idx);
+ /// \brief Reads a TemplateArgumentLoc.
+ TemplateArgumentLoc ReadTemplateArgumentLoc(const RecordData &Record,
+ unsigned &Idx);
+
/// \brief Reads a declarator info from the given record.
- virtual TypeSourceInfo *GetTypeSourceInfo(const RecordData &Record,
- unsigned &Idx);
+ TypeSourceInfo *GetTypeSourceInfo(const RecordData &Record,
+ unsigned &Idx);
+
+ /// \brief Resolve and return the translation unit declaration.
+ TranslationUnitDecl *GetTranslationUnitDecl();
/// \brief Resolve a type ID into a type, potentially building a new
/// type.
- virtual QualType GetType(pch::TypeID ID);
+ QualType GetType(pch::TypeID ID);
/// \brief Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
- virtual Decl *GetDecl(pch::DeclID ID);
+ Decl *GetDecl(pch::DeclID ID);
+ virtual Decl *GetExternalDecl(uint32_t ID);
/// \brief Resolve the offset of a statement into a statement.
///
/// This operation will read a new statement from the external
/// source each time it is called, and is meant to be used via a
/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
- virtual Stmt *GetDeclStmt(uint64_t Offset);
+ virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
/// specified cursor. Read the abbreviations that are at the top of the block
/// and then leave the cursor pointing into the block.
bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID);
+ /// \brief Finds all the visible declarations with a given name.
+ /// The current implementation of this method just loads the entire
+ /// lookup table as unmaterialized references.
+ virtual DeclContext::lookup_result
+ FindExternalVisibleDeclsByName(const DeclContext *DC,
+ DeclarationName Name);
+
/// \brief Read all of the declarations lexically stored in a
/// declaration context.
///
@@ -606,27 +660,8 @@ public:
///
/// \returns true if there was an error while reading the
/// declarations for this declaration context.
- virtual bool ReadDeclsLexicallyInContext(DeclContext *DC,
- llvm::SmallVectorImpl<pch::DeclID> &Decls);
-
- /// \brief Read all of the declarations visible from a declaration
- /// context.
- ///
- /// \param DC The declaration context whose visible declarations
- /// will be read.
- ///
- /// \param Decls A vector of visible declaration structures,
- /// providing the mapping from each name visible in the declaration
- /// context to the declaration IDs of declarations with that name.
- ///
- /// \returns true if there was an error while reading the
- /// declarations for this declaration context.
- ///
- /// FIXME: Using this intermediate data structure results in an
- /// extraneous copying of the data. Could we pass in a reference to
- /// the StoredDeclsMap instead?
- virtual bool ReadDeclsVisibleInContext(DeclContext *DC,
- llvm::SmallVectorImpl<VisibleDeclaration> & Decls);
+ virtual bool FindExternalLexicalDecls(const DeclContext *DC,
+ llvm::SmallVectorImpl<Decl*> &Decls);
/// \brief Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
@@ -691,8 +726,8 @@ public:
Selector DecodeSelector(unsigned Idx);
- virtual Selector GetSelector(uint32_t ID);
- virtual uint32_t GetNumKnownSelectors();
+ virtual Selector GetExternalSelector(uint32_t ID);
+ uint32_t GetNumExternalSelectors();
Selector GetSelector(const RecordData &Record, unsigned &Idx) {
return DecodeSelector(Record[Idx++]);
@@ -704,6 +739,28 @@ public:
NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
unsigned &Idx);
+ /// \brief Read a template name.
+ TemplateName ReadTemplateName(const RecordData &Record, unsigned &Idx);
+
+ /// \brief Read a template argument.
+ TemplateArgument ReadTemplateArgument(const RecordData &Record,unsigned &Idx);
+
+ /// \brief Read a template parameter list.
+ TemplateParameterList *ReadTemplateParameterList(const RecordData &Record,
+ unsigned &Idx);
+
+ /// \brief Read a template argument array.
+ void
+ ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
+ const RecordData &Record, unsigned &Idx);
+
+ /// \brief Read a UnresolvedSet structure.
+ void ReadUnresolvedSet(UnresolvedSetImpl &Set,
+ const RecordData &Record, unsigned &Idx);
+
+ /// \brief Read a C++ base specifier.
+ CXXBaseSpecifier ReadCXXBaseSpecifier(const RecordData &Record,unsigned &Idx);
+
/// \brief Read a source location.
SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
return SourceLocation::getFromRawEncoding(Record[Idx++]);
@@ -729,20 +786,25 @@ public:
/// \brief Reads attributes from the current stream position.
Attr *ReadAttributes();
- /// \brief ReadDeclExpr - Reads an expression from the current decl cursor.
- Expr *ReadDeclExpr();
-
- /// \brief ReadTypeExpr - Reads an expression from the current type cursor.
- Expr *ReadTypeExpr();
+ /// \brief Reads a statement.
+ Stmt *ReadStmt();
- /// \brief Reads a statement from the specified cursor.
- Stmt *ReadStmt(llvm::BitstreamCursor &Cursor);
+ /// \brief Reads an expression.
+ Expr *ReadExpr();
- /// \brief Read a statement from the current DeclCursor.
- Stmt *ReadDeclStmt() {
- return ReadStmt(DeclsCursor);
+ /// \brief Reads a sub-statement operand during statement reading.
+ Stmt *ReadSubStmt() {
+ assert(ReadingKind == Read_Stmt &&
+ "Should be called only during statement reading!");
+ // Subexpressions are stored from last to first, so the next Stmt we need
+ // is at the back of the stack.
+ assert(!StmtStack.empty() && "Read too many sub statements!");
+ return StmtStack.pop_back_val();
}
+ /// \brief Reads a sub-expression operand during statement reading.
+ Expr *ReadSubExpr();
+
/// \brief Reads the macro record located at the given offset.
void ReadMacroRecord(uint64_t Offset);
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index 85f53b9e0302..860ef56a58ff 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -17,6 +17,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/Frontend/PCHBitCodes.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
@@ -38,6 +39,7 @@ class CXXBaseOrMemberInitializer;
class LabelStmt;
class MacroDefinition;
class MemorizeStatCalls;
+class PCHReader;
class Preprocessor;
class Sema;
class SourceManager;
@@ -188,7 +190,11 @@ private:
/// \brief Statements that we've encountered while serializing a
/// declaration or type.
- llvm::SmallVector<Stmt *, 8> StmtsToEmit;
+ llvm::SmallVector<Stmt *, 16> StmtsToEmit;
+
+ /// \brief Statements collection to use for PCHWriter::AddStmt().
+ /// It will point to StmtsToEmit unless it is overriden.
+ llvm::SmallVector<Stmt *, 16> *CollectedStmts;
/// \brief Mapping from SwitchCase statements to IDs.
std::map<SwitchCase *, unsigned> SwitchCaseIDs;
@@ -210,10 +216,13 @@ private:
/// file.
unsigned NumVisibleDeclContexts;
+ /// \brief Write the given subexpression to the bitstream.
+ void WriteSubStmt(Stmt *S);
+
void WriteBlockInfoBlock();
- void WriteMetadata(ASTContext &Context, const char *isysroot);
+ void WriteMetadata(ASTContext &Context, const PCHReader *Chain, const char *isysroot);
void WriteLanguageOptions(const LangOptions &LangOpts);
- void WriteStatCache(MemorizeStatCalls &StatCalls, const char* isysroot);
+ void WriteStatCache(MemorizeStatCalls &StatCalls);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP,
const char* isysroot);
@@ -229,6 +238,11 @@ private:
unsigned ParmVarDeclAbbrev;
void WriteDeclsBlockAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
+
+ void WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+ const char* isysroot);
+ void WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+ const PCHReader *Chain, const char* isysroot);
public:
/// \brief Create a new precompiled header writer that outputs to
@@ -249,7 +263,7 @@ public:
/// \param PPRec Record of the preprocessing actions that occurred while
/// preprocessing this file, e.g., macro instantiations
void WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
- const char* isysroot);
+ const PCHReader *Chain, const char* isysroot);
/// \brief Emit a source location.
void AddSourceLocation(SourceLocation Loc, RecordData &Record);
@@ -299,6 +313,11 @@ public:
/// \brief Emits a reference to a declarator info.
void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record);
+ /// \brief Emits a template argument location info.
+ void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+ const TemplateArgumentLocInfo &Arg,
+ RecordData &Record);
+
/// \brief Emits a template argument location.
void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
RecordData &Record);
@@ -315,6 +334,26 @@ public:
/// \brief Emit a nested name specifier.
void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordData &Record);
+
+ /// \brief Emit a template name.
+ void AddTemplateName(TemplateName Name, RecordData &Record);
+
+ /// \brief Emit a template argument.
+ void AddTemplateArgument(const TemplateArgument &Arg, RecordData &Record);
+
+ /// \brief Emit a template parameter list.
+ void AddTemplateParameterList(const TemplateParameterList *TemplateParams,
+ RecordData &Record);
+
+ /// \brief Emit a template argument list.
+ void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
+ RecordData &Record);
+
+ /// \brief Emit a UnresolvedSet structure.
+ void AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordData &Record);
+
+ /// brief Emit a C++ base specifier.
+ void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, RecordData &Record);
/// \brief Add a string to the given record.
void AddString(const std::string &Str, RecordData &Record);
@@ -335,10 +374,9 @@ public:
/// type or declaration has been written, call FlushStmts() to write
/// the corresponding statements just after the type or
/// declaration.
- void AddStmt(Stmt *S) { StmtsToEmit.push_back(S); }
-
- /// \brief Write the given subexpression to the bitstream.
- void WriteSubStmt(Stmt *S);
+ void AddStmt(Stmt *S) {
+ CollectedStmts->push_back(S);
+ }
/// \brief Flush all of the statements and expressions that have
/// been added to the queue via AddStmt().
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index ec4392fe5d54..f5302947a593 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -18,14 +18,9 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
-namespace llvm {
- class raw_ostream;
-}
-
namespace clang {
class DiagnosticOptions;
class LangOptions;
-class SourceManager;
class TextDiagnosticPrinter : public DiagnosticClient {
llvm::raw_ostream &OS;
@@ -60,14 +55,14 @@ public:
void PrintIncludeStack(SourceLocation Loc, const SourceManager &SM);
- void HighlightRange(const SourceRange &R,
+ void HighlightRange(const CharSourceRange &R,
const SourceManager &SrcMgr,
unsigned LineNo, FileID FID,
std::string &CaretLine,
const std::string &SourceLine);
void EmitCaretDiagnostic(SourceLocation Loc,
- SourceRange *Ranges, unsigned NumRanges,
+ CharSourceRange *Ranges, unsigned NumRanges,
const SourceManager &SM,
const FixItHint *Hints,
unsigned NumHints,
diff --git a/include/clang/Frontend/TypeXML.def b/include/clang/Frontend/TypeXML.def
index 069d718d9def..e8cb4a6de055 100644
--- a/include/clang/Frontend/TypeXML.def
+++ b/include/clang/Frontend/TypeXML.def
@@ -253,6 +253,11 @@ NODE_XML(DependentNameType, "DependentNameType")
ID_ATTRIBUTE_XML
END_NODE_XML
+NODE_XML(DependentTemplateSpecializationType,
+ "DependentTemplateSpecializationType")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
NODE_XML(ObjCInterfaceType, "ObjCInterfaceType")
ID_ATTRIBUTE_XML
END_NODE_XML
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index c1d483164a21..f37cc01a2753 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -65,12 +65,6 @@ void ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts);
void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS,
const PreprocessorOutputOptions &Opts);
-/// RewriteMacrosInInput - Implement -rewrite-macros mode.
-void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS);
-
-/// RewriteMacrosInInput - A simple test for the TokenRewriter class.
-void DoRewriteTest(Preprocessor &PP, llvm::raw_ostream* OS);
-
/// CreatePrintParserActionsAction - Return the actions implementation that
/// implements the -parse-print-callbacks option.
MinimalAction *CreatePrintParserActionsAction(Preprocessor &PP,
diff --git a/include/clang/Index/CallGraph.h b/include/clang/Index/CallGraph.h
index 5edfe6fea8db..336bf47a2efc 100644
--- a/include/clang/Index/CallGraph.h
+++ b/include/clang/Index/CallGraph.h
@@ -54,7 +54,7 @@ public:
class CallGraph {
/// Program manages all Entities.
- idx::Program Prog;
+ idx::Program &Prog;
typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy;
@@ -71,7 +71,7 @@ class CallGraph {
CallGraphNode *ExternalCallingNode;
public:
- CallGraph();
+ CallGraph(idx::Program &P);
~CallGraph();
typedef FunctionMapTy::iterator iterator;
diff --git a/include/clang/Index/Entity.h b/include/clang/Index/Entity.h
index c2aab62e23f2..9863963ff217 100644
--- a/include/clang/Index/Entity.h
+++ b/include/clang/Index/Entity.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
#include <string>
namespace clang {
@@ -71,6 +72,9 @@ public:
/// \returns invalid Entity if an Entity cannot refer to this Decl.
static Entity get(Decl *D, Program &Prog);
+ /// \brief Get an Entity associated with a name in the global namespace.
+ static Entity get(llvm::StringRef Name, Program &Prog);
+
/// \brief true if the Entity is not visible outside the trasnlation unit.
bool isInternalToTU() const {
assert(isValid() && "This Entity is not valid!");
diff --git a/include/clang/Index/Indexer.h b/include/clang/Index/Indexer.h
index 361e729feab2..96c585df2478 100644
--- a/include/clang/Index/Indexer.h
+++ b/include/clang/Index/Indexer.h
@@ -23,6 +23,7 @@
namespace clang {
class ASTContext;
+ class FunctionDecl;
namespace idx {
class Program;
@@ -35,6 +36,7 @@ public:
typedef llvm::DenseMap<ASTContext *, TranslationUnit *> CtxTUMapTy;
typedef std::map<Entity, TUSetTy> MapTy;
typedef std::map<GlobalSelector, TUSetTy> SelMapTy;
+ typedef std::map<Entity, std::pair<FunctionDecl*,TranslationUnit*> > DefMapTy;
explicit Indexer(Program &prog) :
Prog(prog) { }
@@ -49,10 +51,15 @@ public:
virtual void GetTranslationUnitsFor(GlobalSelector Sel,
TranslationUnitHandler &Handler);
+ std::pair<FunctionDecl*, TranslationUnit*> getDefinitionFor(Entity Ent);
+
private:
Program &Prog;
MapTy Map;
+ // Map a function Entity to the its definition.
+ DefMapTy DefMap;
+
CtxTUMapTy CtxTUMap;
SelMapTy SelMap;
};
diff --git a/include/clang/Index/TranslationUnit.h b/include/clang/Index/TranslationUnit.h
index bf9e78f72892..b86ba3ee8a58 100644
--- a/include/clang/Index/TranslationUnit.h
+++ b/include/clang/Index/TranslationUnit.h
@@ -16,6 +16,7 @@
namespace clang {
class ASTContext;
+ class Preprocessor;
namespace idx {
class DeclReferenceMap;
@@ -26,6 +27,7 @@ class TranslationUnit {
public:
virtual ~TranslationUnit();
virtual ASTContext &getASTContext() = 0;
+ virtual Preprocessor &getPreprocessor() = 0;
virtual DeclReferenceMap &getDeclReferenceMap() = 0;
virtual SelectorMap &getSelectorMap() = 0;
};
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index d74124e9c79b..99fe29b22dc2 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -16,6 +16,7 @@
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/StringRef.h"
#include <string>
namespace clang {
@@ -70,6 +71,12 @@ public:
const std::string &Str) {
}
+ /// PragmaMessage - This callback is invoked when a #pragma message directive
+ /// is read.
+ ///
+ virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
+ }
+
/// MacroExpands - This is called by
/// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
/// found.
@@ -127,6 +134,11 @@ public:
Second->PragmaComment(Loc, Kind, Str);
}
+ virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
+ First->PragmaMessage(Loc, Str);
+ Second->PragmaMessage(Loc, Str);
+ }
+
virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
First->MacroExpands(Id, MI);
Second->MacroExpands(Id, MI);
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index ef367feb84db..c68555b2f967 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -14,6 +14,8 @@
#ifndef LLVM_CLANG_PRAGMA_H
#define LLVM_CLANG_PRAGMA_H
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <vector>
@@ -33,12 +35,13 @@ namespace clang {
/// we treat "#pragma STDC" and "#pragma GCC" as namespaces that contain other
/// pragmas.
class PragmaHandler {
- const IdentifierInfo *Name;
+ std::string Name;
public:
- PragmaHandler(const IdentifierInfo *name) : Name(name) {}
+ explicit PragmaHandler(llvm::StringRef name) : Name(name) {}
+ PragmaHandler() {}
virtual ~PragmaHandler();
- const IdentifierInfo *getName() const { return Name; }
+ llvm::StringRef getName() const { return Name; }
virtual void HandlePragma(Preprocessor &PP, Token &FirstToken) = 0;
/// getIfNamespace - If this is a namespace, return it. This is equivalent to
@@ -46,30 +49,38 @@ public:
virtual PragmaNamespace *getIfNamespace() { return 0; }
};
+/// EmptyPragmaHandler - A pragma handler which takes no action, which can be
+/// used to ignore particular pragmas.
+class EmptyPragmaHandler : public PragmaHandler {
+public:
+ EmptyPragmaHandler();
+
+ virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+};
+
/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
/// allowing hierarchical pragmas to be defined. Common examples of namespaces
/// are "#pragma GCC", "#pragma STDC", and "#pragma omp", but any namespaces may
/// be (potentially recursively) defined.
class PragmaNamespace : public PragmaHandler {
- /// Handlers - This is the list of handlers in this namespace.
+ /// Handlers - This is a map of the handlers in this namespace with their name
+ /// as key.
///
- std::vector<PragmaHandler*> Handlers;
+ llvm::StringMap<PragmaHandler*> Handlers;
public:
- PragmaNamespace(const IdentifierInfo *Name) : PragmaHandler(Name) {}
+ explicit PragmaNamespace(llvm::StringRef Name) : PragmaHandler(Name) {}
virtual ~PragmaNamespace();
/// FindHandler - Check to see if there is already a handler for the
- /// specified name. If not, return the handler for the null identifier if it
+ /// specified name. If not, return the handler for the null name if it
/// exists, otherwise return null. If IgnoreNull is true (the default) then
/// the null handler isn't returned on failure to match.
- PragmaHandler *FindHandler(const IdentifierInfo *Name,
+ PragmaHandler *FindHandler(llvm::StringRef Name,
bool IgnoreNull = true) const;
/// AddPragma - Add a pragma to this namespace.
///
- void AddPragma(PragmaHandler *Handler) {
- Handlers.push_back(Handler);
- }
+ void AddPragma(PragmaHandler *Handler);
/// RemovePragmaHandler - Remove the given handler from the
/// namespace.
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index f01b3afc45f5..1ee4bb635179 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -340,13 +340,19 @@ public:
/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
/// If 'Namespace' is non-null, then it is a token required to exist on the
/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
- void AddPragmaHandler(const char *Namespace, PragmaHandler *Handler);
+ void AddPragmaHandler(llvm::StringRef Namespace, PragmaHandler *Handler);
+ void AddPragmaHandler(PragmaHandler *Handler) {
+ AddPragmaHandler(llvm::StringRef(), Handler);
+ }
/// RemovePragmaHandler - Remove the specific pragma handler from
/// the preprocessor. If \arg Namespace is non-null, then it should
/// be the namespace that \arg Handler was added to. It is an error
/// to remove a handler that has not been registered.
- void RemovePragmaHandler(const char *Namespace, PragmaHandler *Handler);
+ void RemovePragmaHandler(llvm::StringRef Namespace, PragmaHandler *Handler);
+ void RemovePragmaHandler(PragmaHandler *Handler) {
+ RemovePragmaHandler(llvm::StringRef(), Handler);
+ }
/// \brief Add the specified comment handler to the preprocessor.
void AddCommentHandler(CommentHandler *Handler);
@@ -871,7 +877,11 @@ private:
//===--------------------------------------------------------------------===//
// Caching stuff.
void CachingLex(Token &Result);
- bool InCachingLexMode() const { return CurPPLexer == 0 && CurTokenLexer == 0;}
+ bool InCachingLexMode() const {
+ // If the Lexer pointers are 0 and IncludeMacroStack is empty, it means
+ // that we are past EOF, not that we are in CachingLex mode.
+ return CurPPLexer == 0 && CurTokenLexer == 0 && !IncludeMacroStack.empty();
+ }
void EnterCachingLexMode();
void ExitCachingLexMode() {
if (InCachingLexMode())
@@ -918,6 +928,7 @@ public:
void HandlePragmaSystemHeader(Token &SysHeaderTok);
void HandlePragmaDependency(Token &DependencyTok);
void HandlePragmaComment(Token &CommentTok);
+ void HandlePragmaMessage(Token &MessageTok);
// Return true and store the first token only if any CommentHandler
// has inserted some tokens and getCommentRetentionState() is false.
bool HandleComment(Token &Token, SourceRange Comment);
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index b5dde9a700e8..bd9b46869a35 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -148,6 +148,7 @@ public:
Kind = tok::unknown;
Flags = 0;
PtrData = 0;
+ UintData = 0;
Loc = SourceLocation();
}
@@ -169,7 +170,7 @@ public:
}
void setLiteralData(const char *Ptr) {
assert(isLiteral() && "Cannot set literal data of non-literal");
- PtrData = (void*)Ptr;
+ PtrData = const_cast<char*>(Ptr);
}
void *getAnnotationValue() const {
@@ -254,4 +255,9 @@ struct PPConditionalInfo {
} // end namespace clang
+namespace llvm {
+ template <>
+ struct isPodLike<clang::Token> { static const bool value = true; };
+} // end namespace llvm
+
#endif
diff --git a/include/clang/Makefile b/include/clang/Makefile
index 6abe375d5e97..e366e4ec4458 100644
--- a/include/clang/Makefile
+++ b/include/clang/Makefile
@@ -1,7 +1,7 @@
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
DIRS := AST Basic Driver
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
install-local::
$(Echo) Installing Clang include files
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index e21da81a8aa8..9cb47aa8da25 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -64,7 +64,21 @@ namespace clang {
/// parse to complete accurately. The MinimalAction class does this
/// bare-minimum of tracking to implement this functionality.
class Action : public ActionBase {
+ /// \brief The parser's current scope.
+ ///
+ /// The parser maintains this state here so that is accessible to \c Action
+ /// subclasses via \c getCurScope().
+ Scope *CurScope;
+
+protected:
+ friend class Parser;
+
+ /// \brief Retrieve the parser's current scope.
+ Scope *getCurScope() const { return CurScope; }
+
public:
+ Action() : CurScope(0) { }
+
/// Out-of-line virtual destructor to provide home for this class.
virtual ~Action();
@@ -1637,16 +1651,39 @@ public:
return move(SubExpr);
}
- /// ActOnCXXNew - Parsed a C++ 'new' expression. UseGlobal is true if the
- /// new was qualified (::new). In a full new like
- /// @code new (p1, p2) type(c1, c2) @endcode
- /// the p1 and p2 expressions will be in PlacementArgs and the c1 and c2
- /// expressions in ConstructorArgs. The type is passed as a declarator.
+ /// \brief Parsed a C++ 'new' expression.
+ ///
+ /// \param StartLoc The start of the new expression, which is either the
+ /// "new" keyword or the "::" preceding it, depending on \p UseGlobal.
+ ///
+ /// \param UseGlobal True if the "new" was qualified with "::".
+ ///
+ /// \param PlacementLParen The location of the opening parenthesis ('(') for
+ /// the placement arguments, if any.
+ ///
+ /// \param PlacementArgs The placement arguments, if any.
+ ///
+ /// \param PlacementRParen The location of the closing parenthesis (')') for
+ /// the placement arguments, if any.
+ ///
+ /// \param TypeIdParens If the type was expressed as a type-id in parentheses,
+ /// the source range covering the parenthesized type-id.
+ ///
+ /// \param D The parsed declarator, which may include an array size (for
+ /// array new) as the first declarator.
+ ///
+ /// \param ConstructorLParen The location of the opening parenthesis ('(') for
+ /// the constructor arguments, if any.
+ ///
+ /// \param ConstructorArgs The constructor arguments, if any.
+ ///
+ /// \param ConstructorRParen The location of the closing parenthesis (')') for
+ /// the constructor arguments, if any.
virtual OwningExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen,
MultiExprArg PlacementArgs,
SourceLocation PlacementRParen,
- bool ParenTypeId, Declarator &D,
+ SourceRange TypeIdParens, Declarator &D,
SourceLocation ConstructorLParen,
MultiExprArg ConstructorArgs,
SourceLocation ConstructorRParen) {
@@ -1769,6 +1806,15 @@ public:
unsigned NumBases) {
}
+ /// ActOnAccessSpecifier - This is invoked when an access specifier
+ /// (and the colon following it) is found during the parsing of a
+ /// C++ class member declarator.
+ virtual DeclPtrTy ActOnAccessSpecifier(AccessSpecifier AS,
+ SourceLocation ASLoc,
+ SourceLocation ColonLoc) {
+ return DeclPtrTy();
+ }
+
/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
/// declarator is parsed. 'AS' is the access specifier, 'BitfieldWidth'
/// specifies the bitfield width if there is one and 'Init' specifies the
@@ -1824,46 +1870,87 @@ public:
//===---------------------------C++ Templates----------------------------===//
- /// ActOnTypeParameter - Called when a C++ template type parameter
- /// (e.g., "typename T") has been parsed. Typename specifies whether
- /// the keyword "typename" was used to declare the type parameter
- /// (otherwise, "class" was used), ellipsis specifies whether this is a
- /// C++0x parameter pack, EllipsisLoc specifies the start of the ellipsis,
- /// and KeyLoc is the location of the "class" or "typename" keyword.
- // ParamName is the name of the parameter (NULL indicates an unnamed template
- // parameter) and ParamNameLoc is the location of the parameter name (if any)
- /// If the type parameter has a default argument, it will be added
- /// later via ActOnTypeParameterDefault. Depth and Position provide
- /// the number of enclosing templates (see
- /// ActOnTemplateParameterList) and the number of previous
- /// parameters within this template parameter list.
+ /// \brief Called when a C++ template type parameter(e.g., "typename T") has
+ /// been parsed.
+ ///
+ /// Given
+ ///
+ /// \code
+ /// template<typename T, typename U = T> struct pair;
+ /// \endcode
+ ///
+ /// this callback will be invoked twice: once for the type parameter \c T
+ /// with \p Depth=0 and \p Position=0, and once for the type parameter \c U
+ /// with \p Depth=0 and \p Position=1.
+ ///
+ /// \param Typename Specifies whether the keyword "typename" was used to
+ /// declare the type parameter (otherwise, "class" was used).
+ ///
+ /// \param Ellipsis Specifies whether this is a C++0x parameter pack.
+ ///
+ /// \param EllipsisLoc Specifies the start of the ellipsis.
+ ///
+ /// \param KeyLoc The location of the "class" or "typename" keyword.
+ ///
+ /// \param ParamName The name of the parameter, where NULL indicates an
+ /// unnamed template parameter.
+ ///
+ /// \param ParamNameLoc The location of the parameter name (if any).
+ ///
+ /// \param Depth The depth of this template parameter, e.g., the number of
+ /// template parameter lists that occurred outside the template parameter
+ /// list in which this template type parameter occurs.
+ ///
+ /// \param Position The zero-based position of this template parameter within
+ /// its template parameter list, which is also the number of template
+ /// parameters that precede this parameter in the template parameter list.
+ ///
+ /// \param EqualLoc The location of the '=' sign for the default template
+ /// argument, if any.
+ ///
+ /// \param DefaultArg The default argument, if provided.
virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
SourceLocation EllipsisLoc,
SourceLocation KeyLoc,
IdentifierInfo *ParamName,
SourceLocation ParamNameLoc,
- unsigned Depth, unsigned Position) {
+ unsigned Depth, unsigned Position,
+ SourceLocation EqualLoc,
+ TypeTy *DefaultArg) {
return DeclPtrTy();
}
- /// ActOnTypeParameterDefault - Adds a default argument (the type
- /// Default) to the given template type parameter (TypeParam).
- virtual void ActOnTypeParameterDefault(DeclPtrTy TypeParam,
- SourceLocation EqualLoc,
- SourceLocation DefaultLoc,
- TypeTy *Default) {
- }
-
- /// ActOnNonTypeTemplateParameter - Called when a C++ non-type
- /// template parameter (e.g., "int Size" in "template<int Size>
- /// class Array") has been parsed. S is the current scope and D is
- /// the parsed declarator. Depth and Position provide the number of
- /// enclosing templates (see
- /// ActOnTemplateParameterList) and the number of previous
- /// parameters within this template parameter list.
+ /// \brief Called when a C++ non-type template parameter has been parsed.
+ ///
+ /// Given
+ ///
+ /// \code
+ /// template<int Size> class Array;
+ /// \endcode
+ ///
+ /// This callback will be invoked for the 'Size' non-type template parameter.
+ ///
+ /// \param S The current scope.
+ ///
+ /// \param D The parsed declarator.
+ ///
+ /// \param Depth The depth of this template parameter, e.g., the number of
+ /// template parameter lists that occurred outside the template parameter
+ /// list in which this template type parameter occurs.
+ ///
+ /// \param Position The zero-based position of this template parameter within
+ /// its template parameter list, which is also the number of template
+ /// parameters that precede this parameter in the template parameter list.
+ ///
+ /// \param EqualLoc The location of the '=' sign for the default template
+ /// argument, if any.
+ ///
+ /// \param DefaultArg The default argument, if provided.
virtual DeclPtrTy ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
unsigned Depth,
- unsigned Position) {
+ unsigned Position,
+ SourceLocation EqualLoc,
+ ExprArg DefaultArg) {
return DeclPtrTy();
}
@@ -1874,29 +1961,50 @@ public:
ExprArg Default) {
}
- /// ActOnTemplateTemplateParameter - Called when a C++ template template
- /// parameter (e.g., "int T" in "template<template <typename> class T> class
- /// Array") has been parsed. TmpLoc is the location of the "template" keyword,
- /// TemplateParams is the sequence of parameters required by the template,
- /// ParamName is the name of the parameter (null if unnamed), and ParamNameLoc
- /// is the source location of the identifier (if given).
+ /// \brief Called when a C++ template template parameter has been parsed.
+ ///
+ /// Given
+ ///
+ /// \code
+ /// template<template <typename> class T> class X;
+ /// \endcode
+ ///
+ /// this callback will be invoked for the template template parameter \c T.
+ ///
+ /// \param S The scope in which this template template parameter occurs.
+ ///
+ /// \param TmpLoc The location of the "template" keyword.
+ ///
+ /// \param TemplateParams The template parameters required by the template.
+ ///
+ /// \param ParamName The name of the parameter, or NULL if unnamed.
+ ///
+ /// \param ParamNameLoc The source location of the parameter name (if given).
+ ///
+ /// \param Depth The depth of this template parameter, e.g., the number of
+ /// template parameter lists that occurred outside the template parameter
+ /// list in which this template parameter occurs.
+ ///
+ /// \param Position The zero-based position of this template parameter within
+ /// its template parameter list, which is also the number of template
+ /// parameters that precede this parameter in the template parameter list.
+ ///
+ /// \param EqualLoc The location of the '=' sign for the default template
+ /// argument, if any.
+ ///
+ /// \param DefaultArg The default argument, if provided.
virtual DeclPtrTy ActOnTemplateTemplateParameter(Scope *S,
SourceLocation TmpLoc,
TemplateParamsTy *Params,
IdentifierInfo *ParamName,
SourceLocation ParamNameLoc,
unsigned Depth,
- unsigned Position) {
+ unsigned Position,
+ SourceLocation EqualLoc,
+ const ParsedTemplateArgument &DefaultArg) {
return DeclPtrTy();
}
- /// \brief Adds a default argument to the given template template
- /// parameter.
- virtual void ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParam,
- SourceLocation EqualLoc,
- const ParsedTemplateArgument &Default) {
- }
-
/// ActOnTemplateParameterList - Called when a complete template
/// parameter list has been parsed, e.g.,
///
@@ -1980,6 +2088,8 @@ public:
/// SS will be "MetaFun::", \p TemplateKWLoc contains the location
/// of the "template" keyword, and "apply" is the \p Name.
///
+ /// \param S The scope in which the dependent template name was parsed.
+ ///
/// \param TemplateKWLoc the location of the "template" keyword (if any).
///
/// \param SS the nested-name-specifier that precedes the "template" keyword
@@ -1995,12 +2105,21 @@ public:
///
/// \param EnteringContext whether we are entering the context of this
/// template.
- virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
+ ///
+ /// \param Template Will be set to the dependent template name, on success.
+ ///
+ /// \returns The kind of template name that was produced. Generally, this will
+ /// be \c TNK_Dependent_template_name. However, if the nested-name-specifier
+ /// is not dependent, or refers to the current instantiation, then we may
+ /// be able to resolve the template kind more specifically.
+ virtual TemplateNameKind ActOnDependentTemplateName(Scope *S,
+ SourceLocation TemplateKWLoc,
CXXScopeSpec &SS,
UnqualifiedId &Name,
TypeTy *ObjectType,
- bool EnteringContext) {
- return TemplateTy();
+ bool EnteringContext,
+ TemplateTy &Template) {
+ return TNK_Non_template;
}
/// \brief Process the declaration or definition of an explicit
@@ -2237,8 +2356,9 @@ public:
/// \param II the identifier we're retrieving (e.g., 'type' in the example).
/// \param IdLoc the location of the identifier.
virtual TypeResult
- ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
- const IdentifierInfo &II, SourceLocation IdLoc) {
+ ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
+ const CXXScopeSpec &SS, const IdentifierInfo &II,
+ SourceLocation IdLoc) {
return TypeResult();
}
@@ -2251,11 +2371,22 @@ public:
/// \param TemplateLoc the location of the 'template' keyword, if any.
/// \param Ty the type that the typename specifier refers to.
virtual TypeResult
- ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
- SourceLocation TemplateLoc, TypeTy *Ty) {
+ ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
+ const CXXScopeSpec &SS, SourceLocation TemplateLoc,
+ TypeTy *Ty) {
return TypeResult();
}
+ /// \brief Called when the parser begins parsing a construct which should not
+ /// have access control applied to it.
+ virtual void ActOnStartSuppressingAccessChecks() {
+ }
+
+ /// \brief Called when the parser finishes parsing a construct which should
+ /// not have access control applied to it.
+ virtual void ActOnStopSuppressingAccessChecks() {
+ }
+
//===----------------------- Obj-C Declarations -------------------------===//
// ActOnStartClassInterface - this action is called immediately after parsing
@@ -2565,7 +2696,9 @@ public:
//===---------------------------- Pragmas -------------------------------===//
enum PragmaOptionsAlignKind {
+ POAK_Native, // #pragma options align=native
POAK_Natural, // #pragma options align=natural
+ POAK_Packed, // #pragma options align=packed
POAK_Power, // #pragma options align=power
POAK_Mac68k, // #pragma options align=mac68k
POAK_Reset // #pragma options align=reset
@@ -2727,7 +2860,27 @@ public:
/// \param NumArgs the number of arguments in \p Args.
virtual void CodeCompleteCall(Scope *S, ExprTy *Fn,
ExprTy **Args, unsigned NumArgs) { }
-
+
+ /// \brief Code completion for the initializer of a variable declaration.
+ ///
+ /// \param S The scope in which the initializer occurs.
+ ///
+ /// \param D The declaration being initialized.
+ virtual void CodeCompleteInitializer(Scope *S, DeclPtrTy D) { }
+
+ /// \brief Code completion after the "return" keyword within a function.
+ ///
+ /// \param S The scope in which the return statement occurs.
+ virtual void CodeCompleteReturn(Scope *S) { }
+
+ /// \brief Code completion for the right-hand side of an assignment or
+ /// compound assignment operator.
+ ///
+ /// \param S The scope in which the assignment occurs.
+ ///
+ /// \param LHS The left-hand side of the assignment expression.
+ virtual void CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) { }
+
/// \brief Code completion for a C++ nested-name-specifier that precedes a
/// qualified-id of some form.
///
@@ -2851,6 +3004,14 @@ public:
unsigned NumMethods) {
}
+ /// \brief Code completion for the receiver in an Objective-C message send.
+ ///
+ /// This code completion action is invoked when we see a '[' that indicates
+ /// the start of an Objective-C message send.
+ ///
+ /// \param S The scope in which the Objective-C message send occurs.
+ virtual void CodeCompleteObjCMessageReceiver(Scope *S) { }
+
/// \brief Code completion for an ObjC message expression that sends
/// a message to the superclass.
///
@@ -2905,7 +3066,7 @@ public:
/// parsed.
virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
unsigned NumProtocols) { }
-
+
/// \brief Code completion for a protocol declaration or definition, after
/// the @protocol but before any identifier.
///
@@ -2995,6 +3156,32 @@ public:
TypeTy *ReturnType,
DeclPtrTy IDecl) {
}
+
+ /// \brief Code completion for a selector identifier or argument name within
+ /// an Objective-C method declaration.
+ ///
+ /// \param S The scope in which this code completion occurs.
+ ///
+ /// \param IsInstanceMethod Whether we are parsing an instance method (or,
+ /// if false, a class method).
+ ///
+ /// \param AtParameterName Whether the actual code completion point is at the
+ /// argument name.
+ ///
+ /// \param ReturnType If non-NULL, the specified return type of the method
+ /// being declared or defined.
+ ///
+ /// \param SelIdents The identifiers that occurred in the selector for the
+ /// method declaration prior to the code completion point.
+ ///
+ /// \param NumSelIdents The number of identifiers provided by SelIdents.
+ virtual void CodeCompleteObjCMethodDeclSelector(Scope *S,
+ bool IsInstanceMethod,
+ bool AtParameterName,
+ TypeTy *ReturnType,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) { }
+
//@}
};
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index 1e6d3ab9760d..b60a94025e09 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -115,6 +115,7 @@ public:
AT_weakref,
AT_weak_import,
AT_reqd_wg_size,
+ AT_init_priority,
IgnoredAttribute,
UnknownAttribute
};
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index 9c19a674732a..0e6dbecb36d6 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -170,6 +170,7 @@ private:
/*TST*/unsigned TypeSpecType : 5;
bool TypeAltiVecVector : 1;
bool TypeAltiVecPixel : 1;
+ bool TypeAltiVecBool : 1;
bool TypeSpecOwned : 1;
// type-qualifiers
@@ -237,6 +238,7 @@ public:
TypeSpecType(TST_unspecified),
TypeAltiVecVector(false),
TypeAltiVecPixel(false),
+ TypeAltiVecBool(false),
TypeSpecOwned(false),
TypeQualifiers(TSS_unspecified),
FS_inline_specified(false),
@@ -278,6 +280,7 @@ public:
TST getTypeSpecType() const { return (TST)TypeSpecType; }
bool isTypeAltiVecVector() const { return TypeAltiVecVector; }
bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; }
+ bool isTypeAltiVecBool() const { return TypeAltiVecBool; }
bool isTypeSpecOwned() const { return TypeSpecOwned; }
void *getTypeRep() const { return TypeRep; }
CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
@@ -885,6 +888,13 @@ struct DeclaratorChunk {
delete[] Exceptions;
}
+ /// isKNRPrototype - Return true if this is a K&R style identifier list,
+ /// like "void foo(a,b,c)". In a function definition, this will be followed
+ /// by the argument type definitions.
+ bool isKNRPrototype() const {
+ return !hasPrototype && NumArgs != 0;
+ }
+
SourceLocation getEllipsisLoc() const {
return SourceLocation::getFromRawEncoding(EllipsisLoc);
}
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 8081c2492b2f..b8c294ada691 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -72,6 +72,7 @@ namespace prec {
class Parser {
friend class PragmaUnusedHandler;
friend class ColonProtectionRAIIObject;
+ friend class ParenBraceBracketBalancer;
PrettyStackTraceParserEntry CrashInfo;
Preprocessor &PP;
@@ -93,7 +94,6 @@ class Parser {
/// and SemaActions for those uses that don't matter.
Action &Actions;
- Scope *CurScope;
Diagnostic &Diags;
/// ScopeCache - Cache scopes to reduce malloc traffic.
@@ -140,7 +140,8 @@ public:
Action &getActions() const { return Actions; }
const Token &getCurToken() const { return Tok; }
-
+ Scope *getCurScope() const { return Actions.getCurScope(); }
+
// Type forwarding. All of these are statically 'void*', but they may all be
// different actual classes based on the actions in place.
typedef Action::ExprTy ExprTy;
@@ -832,8 +833,8 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.9: External Definitions.
DeclGroupPtrTy ParseExternalDeclaration(CXX0XAttributeList Attr);
- bool isDeclarationAfterDeclarator();
- bool isStartOfFunctionDefinition();
+ bool isDeclarationAfterDeclarator() const;
+ bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
AccessSpecifier AS = AS_none);
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
@@ -1059,6 +1060,7 @@ private:
OwningExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
OwningExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
OwningExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
+ bool isSimpleObjCMessageExpression();
OwningExprResult ParseObjCMessageExpression();
OwningExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
SourceLocation SuperLoc,
@@ -1345,14 +1347,14 @@ private:
CreatedScope = true;
P.EnterScope(0); // Not a decl scope.
- if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.CurScope, SS))
+ if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.getCurScope(), SS))
EnteredScope = true;
}
~DeclaratorScopeObj() {
if (EnteredScope) {
assert(SS.isSet() && "C++ scope was cleared ?");
- P.Actions.ActOnCXXExitDeclaratorScope(P.CurScope, SS);
+ P.Actions.ActOnCXXExitDeclaratorScope(P.getCurScope(), SS);
}
if (CreatedScope)
P.ExitScope();
diff --git a/include/clang/Parse/Template.h b/include/clang/Parse/Template.h
index 1f8ccfbf05c6..84f4ed96b4c3 100644
--- a/include/clang/Parse/Template.h
+++ b/include/clang/Parse/Template.h
@@ -58,7 +58,7 @@ namespace clang {
Loc(TemplateLoc), SS(SS) { }
/// \brief Determine whether the given template argument is invalid.
- bool isInvalid() { return Arg == 0; }
+ bool isInvalid() const { return Arg == 0; }
/// \brief Determine what kind of template argument we have.
KindType getKind() const { return Kind; }
diff --git a/include/clang/Rewrite/ASTConsumers.h b/include/clang/Rewrite/ASTConsumers.h
new file mode 100644
index 000000000000..5fb107ccbe0b
--- /dev/null
+++ b/include/clang/Rewrite/ASTConsumers.h
@@ -0,0 +1,45 @@
+//===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// AST Consumers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef REWRITE_ASTCONSUMERS_H
+#define REWRITE_ASTCONSUMERS_H
+
+#include <string>
+
+namespace llvm {
+ class raw_ostream;
+}
+namespace clang {
+
+class ASTConsumer;
+class Diagnostic;
+class LangOptions;
+class Preprocessor;
+
+// ObjC rewriter: attempts tp rewrite ObjC constructs into pure C code.
+// This is considered experimental, and only works with Apple's ObjC runtime.
+ASTConsumer *CreateObjCRewriter(const std::string &InFile,
+ llvm::raw_ostream *OS,
+ Diagnostic &Diags,
+ const LangOptions &LOpts,
+ bool SilenceRewriteMacroWarning);
+
+/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
+/// HTML with syntax highlighting suitable for viewing in a web-browser.
+ASTConsumer *CreateHTMLPrinter(llvm::raw_ostream *OS, Preprocessor &PP,
+ bool SyntaxHighlight = true,
+ bool HighlightMacros = true);
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Frontend/FixItRewriter.h b/include/clang/Rewrite/FixItRewriter.h
index b432d747de97..4ebcef0fff61 100644
--- a/include/clang/Frontend/FixItRewriter.h
+++ b/include/clang/Rewrite/FixItRewriter.h
@@ -12,8 +12,8 @@
// then forwards any diagnostics to the adapted diagnostic client.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_FIX_IT_REWRITER_H
-#define LLVM_CLANG_FRONTEND_FIX_IT_REWRITER_H
+#ifndef LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
+#define LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
@@ -101,4 +101,4 @@ public:
}
-#endif // LLVM_CLANG_FRONTEND_FIX_IT_REWRITER_H
+#endif // LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
diff --git a/include/clang/Rewrite/FrontendActions.h b/include/clang/Rewrite/FrontendActions.h
new file mode 100644
index 000000000000..2ff8d0a5b60a
--- /dev/null
+++ b/include/clang/Rewrite/FrontendActions.h
@@ -0,0 +1,69 @@
+//===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REWRITE_FRONTENDACTIONS_H
+#define LLVM_CLANG_REWRITE_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+class FixItRewriter;
+class FixItPathRewriter;
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class HTMLPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class FixItAction : public ASTFrontendAction {
+protected:
+ llvm::OwningPtr<FixItRewriter> Rewriter;
+ llvm::OwningPtr<FixItPathRewriter> PathRewriter;
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename);
+
+ virtual void EndSourceFileAction();
+
+ virtual bool hasASTFileSupport() const { return false; }
+
+public:
+ FixItAction();
+ ~FixItAction();
+};
+
+class RewriteObjCAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class RewriteMacrosAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class RewriteTestAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/RewriteRope.h b/include/clang/Rewrite/RewriteRope.h
index c0bd741d5546..cb3f8a86f8ab 100644
--- a/include/clang/Rewrite/RewriteRope.h
+++ b/include/clang/Rewrite/RewriteRope.h
@@ -16,6 +16,7 @@
#include <cstring>
#include <cassert>
+#include <cstddef>
#include <iterator>
namespace clang {
diff --git a/include/clang/Rewrite/Rewriter.h b/include/clang/Rewrite/Rewriter.h
index adda86699965..0612a15bbf3f 100644
--- a/include/clang/Rewrite/Rewriter.h
+++ b/include/clang/Rewrite/Rewriter.h
@@ -151,6 +151,7 @@ public:
/// getRangeSize - Return the size in bytes of the specified range if they
/// are in the same file. If not, this returns -1.
int getRangeSize(SourceRange Range) const;
+ int getRangeSize(const CharSourceRange &Range) const;
/// 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
diff --git a/include/clang/Rewrite/Rewriters.h b/include/clang/Rewrite/Rewriters.h
new file mode 100644
index 000000000000..669cf8c208ec
--- /dev/null
+++ b/include/clang/Rewrite/Rewriters.h
@@ -0,0 +1,31 @@
+//===--- Rewriters.h - Rewriter implementations -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains miscellaneous utilities for various front-end actions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REWRITE_REWRITERS_H
+#define LLVM_CLANG_REWRITE_REWRITERS_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+class Preprocessor;
+
+/// RewriteMacrosInInput - Implement -rewrite-macros mode.
+void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS);
+
+/// DoRewriteTest - A simple test for the TokenRewriter class.
+void DoRewriteTest(Preprocessor &PP, llvm::raw_ostream* OS);
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 1f1c0cc11325..1d9d25073177 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -59,6 +59,18 @@ enum {
CCD_InBaseClass = 2
};
+/// \brief Priority value factors by which we will divide or multiply the
+/// priority of a code-completion result.
+enum {
+ /// \brief Divide by this factor when a code-completion result's type exactly
+ /// matches the type we expect.
+ CCF_ExactTypeMatch = 4,
+ /// \brief Divide by this factor when a code-completion result's type is
+ /// similar to the type we expect (e.g., both arithmetic types, both
+ /// Objective-C object pointer types).
+ CCF_SimilarTypeMatch = 2
+};
+
class FunctionDecl;
class FunctionType;
class FunctionTemplateDecl;
@@ -343,6 +355,10 @@ public:
/// method, etc.) should be considered "informative".
bool AllParametersAreInformative : 1;
+ /// \brief Whether we're completing a declaration of the given entity,
+ /// rather than a use of that entity.
+ bool DeclaringEntity : 1;
+
/// \brief If the result should have a nested-name-specifier, this is it.
/// When \c QualifierIsInformative, the nested-name-specifier is
/// informative rather than required.
@@ -356,7 +372,7 @@ public:
Priority(getPriorityFromDecl(Declaration)), StartParameter(0),
Hidden(false), QualifierIsInformative(QualifierIsInformative),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- Qualifier(Qualifier) {
+ DeclaringEntity(false), Qualifier(Qualifier) {
}
/// \brief Build a result that refers to a keyword or symbol.
@@ -364,21 +380,21 @@ public:
: Kind(RK_Keyword), Keyword(Keyword), Priority(Priority),
StartParameter(0), Hidden(false), QualifierIsInformative(0),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- Qualifier(0) { }
+ DeclaringEntity(false), Qualifier(0) { }
/// \brief Build a result that refers to a macro.
Result(IdentifierInfo *Macro, unsigned Priority = CCP_Macro)
: Kind(RK_Macro), Macro(Macro), Priority(Priority), StartParameter(0),
Hidden(false), QualifierIsInformative(0),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- Qualifier(0) { }
+ DeclaringEntity(false), Qualifier(0) { }
/// \brief Build a result that refers to a pattern.
Result(CodeCompletionString *Pattern, unsigned Priority = CCP_CodePattern)
: Kind(RK_Pattern), Pattern(Pattern), Priority(Priority),
StartParameter(0), Hidden(false), QualifierIsInformative(0),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- Qualifier(0) { }
+ DeclaringEntity(false), Qualifier(0) { }
/// \brief Retrieve the declaration stored in this result.
NamedDecl *getDeclaration() const {
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
index d27e29281b5a..ad42a847fa48 100644
--- a/include/clang/Sema/ExternalSemaSource.h
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -29,6 +29,8 @@ public:
ExternalASTSource::SemaSource = true;
}
+ ~ExternalSemaSource();
+
/// \brief Initialize the semantic source with the Sema instance
/// being used to perform semantic analysis on the abstract syntax
/// tree.